Предложение 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 не всегда плох, и это не означает, что файл сохраняется на диске. Если размер данных небольшой,он выполняется в памяти.