CREATE TABLE `TEST` (
`ID1` mediumint(8) NOT NULL default '0',
`ID2` mediumint(8) NOT NULL default '0',
`DATE` datetime NOT NULL default '0000-00-00 00:00:00',
UNIQUE KEY `COMBO_INDEX` (`ID1`,`ID2`),
KEY `ID2` (`ID2`)
) ENGINE=InnoDB`
这张表大约有16196496条记录
EXPLAIN SELECT * FROM TEST WHERE ID1 IN ('8518582', '5398912', '6120243', '6841316', '7580078', '7671953', '7775737', '7792470', '7887985', '7888375', '7946516', '8008760', '8111722', '8211235', '8262746', '8365675', '8396853', '8399818', '8410062', '8459079', '8490683')
我得到输出为
+----+-------------+------------------------+------+---------------+------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------------+------+---------------+------+---------+------+----------+-------------+
| 1 | SIMPLE | TEST | ALL | ID1 | NULL | NULL | NULL | 16196496 | Using where |
+----+-------------+------------------------+------+---------------+------+---------+------+----------+-------------+
我不明白为什么查询没有使用任何键。
此外,当我在此 innodb 表中运行此查询时,它花费了大量时间 329 秒(MySQL 版本 5.0.45-log)。
虽然如果我在 myisam 表上运行相同的查询,它只需要 2 秒(尽管解释它显示相同的结果)。我使用的是 MySQL 5.5 版。
为什么查询没有使用任何键?
最佳答案
innodb
需要一个主键来快速查找在索引中找到的行。只要你没有任何 - mysql 无法做到这一点,所以它更喜欢全扫描。
http://dev.mysql.com/doc/refman/5.6/en/innodb-table-and-index.html
Accessing a row through the clustered index is fast because the index search leads directly to the page with all the row data. If a table is large, the clustered index architecture often saves a disk I/O operation when compared to storage organizations that store row data using a different page from the index record. (For example, MyISAM uses one file for data rows and another for index records.)
所以显而易见的解决方案 - 是用主键替换唯一键(尽管我个人不喜欢自然主键,尤其是复合自然主键)。
PS:似乎我在关于使用数字而不是字符串的评论中的猜测有所帮助。尽管关于添加主键的建议仍然有效 - 这样做可以获得更好的性能。
关于Mysql查询没有使用任何键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14317412/