我有一个包含数百万条记录的表,当前表的大小为 2GB,预计会进一步增长
表结构
CREATE TABLE `test` (
`column_1` int(11) NOT NULL AUTO_INCREMENT,
`column_2` int(11) NOT NULL,
`column_3` int(11) NOT NULL,
`column_4` int(11) NOT NULL,
`column_5` datetime NOT NULL,
`column_6` time NOT NULL,
PRIMARY KEY (`column_1`),
UNIQUE KEY `index_1` (`column_2`,`column_3`),
UNIQUE KEY `index_2` (`column_2`,`column_4`),
KEY `index_3` (`column_3`),
KEY `index_4` (`column_4`),
KEY `index_5` (`column_2`),
KEY `index_6` (`column_5`,`column_2`),
CONSTRAINT `fk_1` FOREIGN KEY (`column_3`) REFERENCES `test2`(`id`),
CONSTRAINT `fk_2` FOREIGN KEY (`column_4`) REFERENCES `test2` (`id`),
CONSTRAINT `fl_3` FOREIGN KEY (`column_2`) REFERENCES `link` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14164023 DEFAULT CHARSET=utf8;
当我运行以下查询时,column_2 的不同值大约需要 5-8 秒。有人可以帮助更好地执行这一任务吗?
SELECT count(*) FROM test WHERE test.column_2= 26 and
test.column_5 between '2015-06-01 00:00:00' AND
'2015-06-30 00:00:00' ;
注意:所提到的时间是通过在 mysql 工作台上执行查询来捕获的
最佳答案
您的index_6
当前有column_5
,然后是column_2
,因此MySQL首先尝试根据BETWEEN
进行过滤条款。然而MySQL有一个限制,即在范围模式下使用索引后,它不能使用索引的第二部分(更多信息参见此blog post)。
优化此类查询的正确方法是将equation列作为索引的第一部分,将range列作为第二部分。然后 MySQL 将选择 column_2
值为 26
的行,然后使用索引的第二部分根据 column_5
日期范围进一步过滤它们。
所以解决方案是有一个索引:
KEY `ind_c2_c5` (`column_2`,`column_5`)
顺便说一句,最好为索引提供描述性名称,这样您第一眼就知道它们的用途......
关于mysql - 针对大小超过 2GB 的表调整 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31404641/