【发布时间】:2016-08-26 11:53:17
【问题描述】:
我使用的是 MySQL 5.6,我的存储引擎是 InnoDB。
我有一个包含 100 万行的表格:
- ID(主键)
- 名字
- 姓氏
- foreign_key_id(外键,NOT NULL)
- foreign_key_id2(另一个外键,默认为NULL)
这些行被分隔在:
- 25%,foreign_key_id 值为 1 且 foreign_key_id2 NULL
- 25%,foreign_key_id 值为 1 且 foreign_key_id2 非空
- 25%,foreign_key_id 值为 2 且 foreign_key_id2 NULL
- 25%,foreign_key_id 值为 2 且 foreign_key_id2 非空
具有以下索引:
- foreign_key_id 上的索引 foreign_key_idx
- 索引 foreign_key_2_idx 和 foreign_key_id2
- (foreign_key_idx, foreign_key_2_idx) 上的复合索引 foreign_key_comp_idx
我执行以下查询:
查询 1 - 没有索引:
SELECT *
FROM table tbl
IGNORE INDEX(foreign_key_idx, foreign_key_2_idx, foreign_key_comp_idx)
WHERE tbl.foreign_key_id = 1 AND tbl.foreign_key_id2 IS NOT NULL
查询 2 - 有索引(无复合索引):
SELECT *
FROM table tbl
IGNORE INDEX(foreign_key_comp_idx)
WHERE tbl.foreign_key_id = 1 AND tbl.foreign_key_id2 IS NOT NULL
查询 3 - 使用复合索引(没有其他索引):
SELECT *
FROM table tbl
IGNORE INDEX(foreign_key_idx, foreign_key_2_idx)
WHERE tbl.foreign_key_id = 1 AND tbl.foreign_key_id2 IS NOT NULL
结果:
查询 1(无索引)执行 全表扫描,并使用 100 万条记录 总时长 0.37 秒。
查询 2(索引,无复合索引)对 foreign_key_idx 索引执行非唯一键查找,并且 使用 50 万条记录,总持续时间为 0.6 秒。
查询 3(仅限复合索引)对 复合索引 执行 索引范围扫描,并使用 480K 总时长0.13秒的记录。
我真正不明白的是:为什么 query 2(有索引)总是比 query 1(没有索引)执行得慢?我真的很困,需要一些帮助......
我已经用不同的行数测试了上面的查询,例如 1k、10k、20k、50k、100k、200k、250k、500k、1M 等,总是以相同的比率 (25%),结果相同(查询 2 总是执行缓慢)
提前感谢您,非常感谢您的任何意见!
编辑(2016 年 5 月 2 日)
显示创建表命令:
CREATE TABLE `table` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FirstName` varchar(255) NOT NULL,
`LastName` varchar(255) NOT NULL,
`foreign_key_id` int(11) NOT NULL,
`foreign_key_id2` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `foreign_key_idx` (`foreign_key_id`),
KEY `foreign_key_2_idx` (`foreign_key_id2`),
KEY `foreign_key_comp_idx ` (`foreign_key_id`,`foreign_key_id2`),
CONSTRAINT `foreign_key_idx` FOREIGN KEY (`foreign_key_id`) REFERENCES `table2` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `foreign_key_2_idx` FOREIGN KEY (`foreign_key_id2`) REFERENCES `table3` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB AUTO_INCREMENT=1515998 DEFAULT CHARSET=latin1
不确定是否重要,但 table2 有 20 条记录,table3 也有 100 万条记录。
【问题讨论】:
-
在我深入研究之前请提供
SHOW CREATE TABLE。还为每个提供EXPLAIN SELECT ...输出。 -
@RickJames 谢谢。添加了 CREATE TABLE 和 EXPLAINS!
标签: mysql optimization indexing innodb mysql-workbench