我已经阅读了几个关于此问题的其他堆栈溢出问题,但它仍然没有意义。MySQL没有使用索引来排序
我与sakila的世界测试数据库进行试验,这是我的表定义:
CREATE TABLE `City` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `CountryCode` (`CountryCode`),
KEY `city_name` (`Name`),
CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `Country` (`Code`)
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1
这里是我的指标:
mysql> show index from City;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| City | 0 | PRIMARY | 1 | ID | A | 4188 | NULL | NULL | | BTREE | | |
| City | 1 | CountryCode | 1 | CountryCode | A | 465 | NULL | NULL | | BTREE | | |
| City | 1 | city_name | 1 | Name | A | 4188 | NULL | NULL | | BTREE | | |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
我试图理解为什么MySQL是不使用这里对结果进行排序的索引:
mysql> explain select * from City order by Name asc;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | City | ALL | NULL | NULL | NULL | NULL | 4188 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
我不明白为什么MySQL在这个文件夹中做文件情况下,很明显城市名称上的索引已经排序。
我看了一些其他的问题,人们在他们的索引中使用前缀,这是禁止MySQL使用该索引进行排序。当我在名称上创建该索引时,我没有使用前缀。
其他人也期待在Extra列中看到“使用索引”。我的理解是,这意味着索引'覆盖'了查询,这意味着实际的表不需要被读取,因为索引具有所有的值。所以我不希望在额外列中看到这一点,因为索引仅在名称上,还有其他列。
我觉得这个术语“使用索引”有点让人误解,MySQL可以使用索引来过滤结果,但仍然需要读取表格。在这种情况下,“使用索引”不会成为Extra列的一部分。太误导了。
有人请向我解释为什么MySQL仍然在使用该查询的文件?如果你想知道的话,有4079行。
另外,是否有任何明确的方法知道MySQL使用索引来排序结果?
优化器看到您将读取表中的所有记录,因此它倾向于从PRIMARY索引读取而不是从辅助city_name读取。因此MySQL必须做额外的排序。 – akuzminsky