Я прочитал несколько других вопросов о переполнении стека об этом сейчас, и это все еще не имеет смысла.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 делает fileort в этом случай, довольно очевидно, что индекс в имени города уже отсортирован.
Я просмотрел некоторые другие вопросы, люди использовали префиксы в своем индексе, что запрещало MySQL использовать этот индекс для сортировки. Я не использовал префикс, когда создавал этот индекс по имени.
Также другие люди ожидали увидеть «Использование индекса» в столбце «Дополнительно». Я понимаю, что это означает, что индекс «охватывает» запрос, а это означает, что фактическую таблицу не нужно было читать, поскольку индекс имел все значения. Поэтому я не ожидаю увидеть это в столбце «Дополнительно», потому что индекс относится только к имени и есть другие столбцы.
Я чувствую, что термин «Использование индекса» немного вводит в заблуждение, MySQL может использовать индекс для фильтрации результатов, но все равно должен прочитать таблицу. В этом случае «Использование индекса» не будет частью столбца «Дополнительно». Слишком вводящий в заблуждение.
Может кто-нибудь объяснить мне, почему MySQL все еще использует файловый порт для этого запроса? На случай, если вы хотите знать, есть 4079 строк.
Также есть ли ясный способ узнать, что MySQL использовал индекс для сортировки результатов?
Оптимизатор видит, что вы будете читать все записи из таблицы, поэтому он предпочитает чтение из индекса PRIMARY вместо вторичного city_name. Таким образом, MySQL должен выполнить дополнительную сортировку. – akuzminsky