mysql - 针对大小超过 2GB 的表调整 SQL 查询

标签 mysql mysql-workbench

我有一个包含数百万条记录的表,当前表的大小为 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/

相关文章:

mysql - 优化多表mysql/php的连接查询

来自变量的 mysql 别名

mysql - 在哪里设置mysql一周的第一天?

Mysql View 在表为空时返回数据

MySQL Workbench 错误地声称我的语法有错误

mysql - 如何在已存在且有数据的表中创建 AUTO_INCREMENT 列?

php - mySQL 中的复杂查询(在多个表中搜索用户)

php - 防止mysql MyISAM表崩溃

MySQL 工作台 ALTER USER 语句

mysql - MySQL Workbench 6.0 存储过程出现语法错误