Как узнать, какие индексы задействованы в SQL-запросе?

Ответ

Основной инструмент для анализа использования индексов — оператор EXPLAIN (или EXPLAIN ANALYZE для более детальной информации).

Пример в MySQL:

EXPLAIN SELECT id, name FROM users WHERE email = 'user@example.com' AND active = 1;

Ключевые поля в выводе EXPLAIN:

  • possible_keys: Какие индексы могли бы быть использованы.
  • key: Какой индекс фактически был использован.
  • key_len: Длина используемой части индекса.
  • type: Тип соединения (например, ref, range, index, ALL для полного сканирования).
  • rows: Оценочное количество строк для проверки.

Дополнительные команды для работы с индексами:

-- Показать все индексы для таблицы
SHOW INDEX FROM users;

-- Принудительно предложить оптимизатору использовать конкретный индекс
SELECT * FROM users USE INDEX (idx_email) WHERE email LIKE 'a%';

-- Проанализировать таблицу для обновления статистики, используемой оптимизатором
ANALYZE TABLE users;

Практический пример анализа: Если EXPLAIN показывает type: ALL для большой таблицы, это признак отсутствия подходящего индекса. Создание индекса по полям WHERE или JOIN обычно решает проблему.

-- Создание составного индекса для запроса выше
CREATE INDEX idx_email_active ON users(email, active);
-- После этого повторный EXPLAIN должен показать использование этого индекса (key: idx_email_active).

Ответ 18+ 🔞

Давай разберёмся, как эта штука работает, а то я уже вижу, как у тебя глаза на лоб лезут. Слушай, главный наш друг в этом деле — оператор EXPLAIN. Ну или EXPLAIN ANALYZE, если ты хочешь докопаться до самой сути и посмотреть, сколько реально времени запрос сосёт.

Вот смотри, как в MySQL это выглядит:

EXPLAIN SELECT id, name FROM users WHERE email = 'user@example.com' AND active = 1;

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

  • possible_keys: Это какие индексы, в принципе, могли бы пригодиться. Но это не значит, что их возьмут — оптимизатор иногда такой хитрожопый, сам от себя охуеешь.
  • key: А вот это уже по факту — какой индекс реально использовали. Если тут NULL, а таблица большая — это пиздец, Карл, полный.
  • key_len: Показывает, какую часть индекса отгрызли для работы. Полезно, чтобы понять, используется ли составной индекс целиком или только кусочек.
  • type: Тип доступа к данным. Самый страшный зверь тут — ALL. Это значит, что база пошла читать всю таблицу от корки до корки. Если таблица на миллион строк — будет вам хиросима и нагасаки, терпения ноль ебать.
  • rows: Ну, это сколько строк, по мнению базы, придётся перелопатить. Цифра обычно оценочная, иногда очень оптимистичная.

Ещё есть команды, которые в хозяйстве пригодятся:

-- Показать все индексы, которые на таблице висят. Как на ёлке игрушки.
SHOW INDEX FROM users;

-- Можно попробовать наставить оптимизатору мозги, мол, используй вот этот индекс, дурак.
SELECT * FROM users USE INDEX (idx_email) WHERE email LIKE 'a%';

-- Иногда база тупит, потому что статистика по таблице устарела. Этой командой её по голове стукнешь — она протрезвеет.
ANALYZE TABLE users;

А теперь практика, без неё нихуя не понятно. Допустим, ты сделал EXPLAIN, а там красуется type: ALL для таблицы, где данных — овердохуища. Это прямой намёк, что твой запрос — это мартышлюшка с гранатой, он всё взорвёт.

Решение? Создать нормальный индекс! Для нашего примера запроса можно сделать составной:

-- Делаем индекс сразу по двум полям из WHERE
CREATE INDEX idx_email_active ON users(email, active);

После этого снова делаешь EXPLAIN. Если всё правильно, в поле key теперь должен быть idx_email_active, а type станет чем-то вроде ref. Вот тогда можно выдохнуть — запрос перестал жрать ресурсы как не в себя.