Предложение MySQL Order by с использованием " FileSort"

у меня есть структура таблицы, как

comment_id primary key
comment_content 
comment_author
comment_author_url

когда я запускаю запрос, как

explain SELECT * FROM comments  ORDER BY comment_id

Он выводит результаты в виде

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  comments    ALL     NULL    NULL    NULL    NULL    22563   Using filesort

почему не удается найти индекс, который я определил как первичный ключ?

2 ответов


в любое время сортировка не может быть выполнена из индекса, это filesort.

странно, что у вас должен быть индекс в этом поле, так как это первичный ключ(и столбец первичного ключа неявно индексируется), тестирование на тестовой базе данных я только что заметил, что MySQL использует FileSort в любое время, когда вы выполняете SELECT *, это бессмысленное поведение (я знаю), но если вы перепишете свой запрос таким образом:

SELECT comment_id, comment_content, comment_author, comment_author_url 
FROM comments  
ORDER BY comment_id

он будет использовать индекс правильно . Может быть ... ошибка mysql ...


это не потому, что он не может использовать индекс. Это потому, что оптимизатор считает, что быстрее не использовать индекс и делать filesort1. Вы должны увидеть различное поведение в таблицах MyiSAM и InnoDB.

InnoDB создает PRIMARY ключ как кластеризованный (или первый UNIQUE если первичный не определен), и это можно использовать для запросов, которые имеют ORDER BY pk или WHERE pk BETWEEN low AND high потому что все необходимые значения находятся в этом кластеризованном ключе и последовательно местоположения (кластеризованный ключ is таблица).

таблицы MyISAM имеют только индексы B-дерева, поэтому, если запрос использовал этот индекс, он должен был бы прочитать весь индекс, и у него было бы comment_id значения в нужном порядке (это действительно хорошо), но тогда он должен был бы также прочитать таблицу (не так хорошо), чтобы получить все остальные нужные столбцы. Итак, оптимизатор думает, что, поскольку он собирается прочитать таблицу, почему бы не сканировать все это и не сделать filesort? Вы можете проверить это пытаюсь:

SELECT comment_id FROM comments  ORDER BY comment_id ;

он будет использовать индекс и не делать filesort, потому что запрос нуждается только в значениях, которые хранятся в индексе.


если вы хотите аналогичное (InnoDB) поведение в MyiSAM, вы можете попробовать создать индекс на (comment_id, comment_content, comment_author, comment_author_url) а затем попробуйте свой запрос. Все необходимые значения будут найдены в индексе и в правильном порядке, поэтому filesort не будет выполняться.

дополнительный индекс, конечно, потребуется почти столько же места на диске, сколько таблица.


1: filesort не всегда плох, и это не означает, что файл сохраняется на диске. Если размер данных небольшой,он выполняется в памяти.