我有一个MySQL数据库,结构如下:
mysql> describe company;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
mysql> describe nameserver;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| companyId | int | NO | MUL | NULL | |
| ns | varchar(250) | NO | MUL | NULL | |
+-----------+--------------+------+-----+---------+----------------+
mysql> describe domain;
+--------------+--------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+-------------------+
| id | int | NO | PRI | NULL | auto_increment |
| nameserverId | int | NO | MUL | NULL | |
| domain | varchar(250) | NO | MUL | NULL | |
| tld | varchar(20) | NO | MUL | NULL | |
| createDate | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updatedAt | datetime | YES | | NULL | |
| status | tinyint | NO | | NULL | |
| fileNo | smallint | NO | MUL | NULL | |
+--------------+--------------+------+-----+-------------------+-------------------+
索引结构:
-- Indexes for table `company`
--
ALTER TABLE `company`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `domain`
--
ALTER TABLE `domain`
ADD PRIMARY KEY (`id`),
ADD KEY `nameserver` (`nameserverId`),
ADD KEY `domain` (`domain`),
ADD KEY `tld` (`tld`),
ADD KEY `fileNo` (`fileNo`);
--
-- Indexes for table `nameserver`
--
ALTER TABLE `nameserver`
ADD PRIMARY KEY (`id`),
ADD KEY `company` (`companyId`),
ADD KEY `ns` (`ns`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `company`
--
ALTER TABLE `company`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `domain`
--
ALTER TABLE `domain`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `nameserver`
--
ALTER TABLE `nameserver`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `domain`
--
ALTER TABLE `domain`
ADD CONSTRAINT `nameserver` FOREIGN KEY (`nameserverId`) REFERENCES `nameserver` (`id`);
--
-- Constraints for table `nameserver`
--
ALTER TABLE `nameserver`
ADD CONSTRAINT `company` FOREIGN KEY (`companyId`) REFERENCES `company` (`id`);
数据量如下:
domain table about 500 millions records
nameserver table about 2 millions records
运行此查询大约需要4个小时才能得到结果:
SELECT distinct domain FROM domain
INNER join nameserver on nameserver.id = domain.nameserverId
WHERE nameserver.companyId = 2
上述查询的解释结果:
+----+-------------+------------+------------+------+-------------------
+------------+---------+-----------------------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+-------------------+------------+---------+-----------------------+------+----------+------------------------------+
| 1 | SIMPLE | nameserver | NULL | ref | PRIMARY,company | company | 4 | const | 1738 | 100.00 | Using index; Using temporary |
| 1 | SIMPLE | domain | NULL | ref | nameserver,domain | nameserver | 4 | tldzone.nameserver.id | 716 | 100.00 | NULL |
+----+-------------+------------+------------+------+-------------------+------------+---------+-----------------------+------+----------+------------------------------+
我的问题是如何提高从这个数据库获取查询的速度?
对我来说,改变DB结构甚至用另一个DBMS替换它是可能的。
MySQL运行在一个8.0 GB RAM和双核CPU的VPS上。
2条答案
按热度按时间t3psigkw1#
(“穆尔”并不告诉我您是否已经拥有这两个复合索引中的任何一个。
SHOW CREATE TABLE
比DESCRIBE
更具描述性。)ugmeyewa2#
1向相关列添加索引:向nameserver和domain表中的companyId、nameserverId和domain列添加索引可以帮助数据库快速定位相关行,从而加快查询速度。
2使用覆盖指数:覆盖索引是包含查询中使用的所有列的索引。通过在companyId、nameserverId和domain列上创建覆盖索引,可以避免数据库在实际表中查找数据,从而提高查询性能。
3使用列存储索引:列存储索引是按列而不是按行存储数据的索引。列存储索引可以更有效地查询大型数据集,并可以提高所提供查询的性能。
4使用针对大型数据集优化的数据库管理系统:如果您使用的数据库管理系统不太适合处理大型数据集,则切换到其他系统可能会提高性能。要考虑的一些选项包括面向列的数据库管理系统(如Vertica或ClickHouse)或分布式数据库管理系统(如Cassandra或HBase)。
5考虑使用分布式数据库:如果您有一个非常大的数据集,但查询性能仍然很低,则可能需要考虑使用分布式数据库管理系统,该系统允许您将数据分布在多个服务器上,并可以提高数据库的可伸缩性和性能。
6请记住,最适合您的具体解决方案将取决于您的数据库的具体要求和您在数据库上放置的工作负载。执行一些基准测试和测试以确定哪些方法最适合您的需要可能会有所帮助。