Как интерпретировать вывод MySQL EXPLAIN?

Я хочу выбрать содержимое столбца text из entrytable.

EXPLAIN SELECT text
FROM entrytable
WHERE user = 'username' &&
`status` = '1' && (
    `status_spam_user` = 'no_spam'
    || (
        `status_spam_user` = 'neutral' &&
        `status_spam_system` = 'neutral'
    )
)
ORDER BY datum DESC
LIMIT 6430 , 10

Таблица имеет три индекса:

  • index_user (пользователь)
  • index_datum (datum)
  • index_status_mit_spam (status, status_spam_user, status_spam_system)

Результат EXPLAIN:

id  select_type     table       type    possible_keys                       key         key_len     ref     rows    Extra
1   SIMPLE          entrytable  ref     index_user,index_status_mit_spam    index_user  32          const   7800    Using where; Using filesort
  • Являются ли possible_keys индексы MySQL, которые могут захотеть использовать, и keys индексы MySQL фактически используют?
  • Почему индекс index_status_mit_spam не используется? В запросе столбцы имеют тот же порядок, что и в индексе,...
  • Почему индекс index_datum не используется для ORDER BY?
  • Как я могу оптимизировать свои таблицы-индексы или запрос? (Запрос выше требует до 3 секунд, имея около миллиона записей в таблице).

Ответ 1

Отвечая на ваши вопросы:

  • Является possible_keys индексов MySQL, возможно, захотите использовать и keys индексов MySQL фактически использует? Да, это правильно.

  • Почему индекс index_status_mit_spam не используется? В запросе столбцы имеют тот же порядок, что и в индексе. SQL использует статистику по индексам таблиц, чтобы определить, какой индекс использовать. Порядок полей в операторе выбора никак не влияет на то, какой индекс использовать. Статистика вокруг индексов включает такую информацию, как уникальность индекса и другие вещи. Вероятно, будут использованы более уникальные индексы. Подробнее об этом читайте здесь: http://dev.mysql.com/doc/innodb/1.1/en/innodb-other-changes-statistics-estima.html или здесь: http://dev.mysql.com/doc/refman/5.0/ru//myisam-index-statistics.html. Эти факторы определяют, как MySQL выберет один индекс для использования. Он будет использовать только один индекс.

  • Почему индекс index_datum не используется для ORDER BY? MySQL будет использовать только один индекс, а не два во время запроса, так как использование второго индекса еще больше замедлит запрос. Чтение индекса НЕ читает таблицу. Это связано с операционной эффективностью запроса. Вот ответы, которые могут объяснить некоторые концепции: https://dba.stackexchange.com/questions/18528/performance-difference-between-clustered-and-non-clustered-index/18531#18531 или Добавление предельного предложения в запрос MySQL замедляется это резко или MySQL индексы и когда их сгруппировать. Эти ответы содержат много деталей, которые помогут вам понять индексацию MySQL.

  • Как я могу оптимизировать свои табличные индексы или запрос? (Приведенный выше запрос требует до 3 секунд, имея около миллиона записей в таблице). Ну, здесь есть сортировка файлов, которая, вероятно, замедляет вас. Возможно, в таблице слишком много индексов, а MySQL выбирает неправильный.

Вы должны понимать, что индексы ускоряют чтение и замедляют запись в таблицы. Так что просто добавление индексов не всегда хорошая идея. Приведенные выше ответы и указатели должны помочь вам получить твердое понимание.

Ответ 2

  • possible_keys обозначает все индексы вашей таблицы (ключи или столбцы индекса)
  • Оптимизатор MySQL решает наилучший способ EXECUTE запроса, он может использовать любой индекс (необязательный первичный ключ) или none
  • Чтобы заставить MySQL использовать или игнорировать индекс, указанный в столбце possible_keys, используйте FORCE INDEX, USE INDEX или IGNORE INDEX в вашем запросе
  • Отметьте эту ссылку - http://dev.mysql.com/doc/refman/5.1/en/index-hints.html.

    Вы можете указать область подсказки индекса, добавив предложение FOR в подсказку. Это обеспечивает более мелкомасштабный контроль над выбором оптимизатора плана выполнения для различных этапов обработки запросов. Чтобы повлиять только на индексы, используемые, когда MySQL решает, как найти строки в таблице и как обрабатывать объединения, используйте FOR JOIN. Чтобы повлиять на использование индекса для сортировки или группировки строк, используйте FOR ORDER BY или FOR GROUP BY. (Однако, если для таблицы есть индекс покрытия и он используется для доступа к таблице, оптимизатор будет игнорировать подсказки IGNORE INDEX FOR {ORDER BY | GROUP BY}, которые запрещают этот индекс.)

  • Попробуйте использовать другой индекс - проверьте эту ссылку наверняка - Использование MySQL` FORCE INDEX`?

  • Понять выходной формат EXPLAIN - http://dev.mysql.com/doc/refman/5.1/en/explain-output.html