Как команда EXPLAIN помогает в оптимизации SQL-запросов

Ответ

Команда EXPLAIN (или EXPLAIN ANALYZE в некоторых СУБД) — это ключевой инструмент для анализа производительности SQL-запросов. Она не выполняет запрос, а показывает план выполнения, который выбрал оптимизатор базы данных для получения данных.

Что можно узнать из плана выполнения:

  • Порядок соединения таблиц (JOIN).
  • Способ доступа к данным: полное сканирование таблицы (Full Table Scan) или использование индекса (Index Scan).
  • Используемые индексы (если есть).
  • Примерное количество строк, которые будут обработаны на каждом шаге.
  • Необходимость во временных таблицах или сортировке (Using temporary, Using filesort).

Практический пример:

Предположим, запрос к большой таблице users выполняется медленно:

SELECT * FROM users WHERE email = 'test@example.com';

Выполним EXPLAIN для этого запроса:

EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

Если в выводе мы видим type: ALL, это означает полный перебор таблицы (Full Table Scan) — самое узкое место. Оптимизатор вынужден проверять каждую строку, чтобы найти нужную.

Решение:

Создадим индекс для колонки email:

CREATE INDEX idx_users_email ON users(email);

После этого повторный вызов EXPLAIN покажет, что type изменился на ref или const, а в поле key будет указан наш новый индекс idx_users_email. Это означает, что база данных теперь может мгновенно найти нужные строки с помощью индекса, что кардинально ускоряет запрос.

Ответ 18+ 🔞

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

И что же там можно разглядеть, спросишь ты? А вот что, ёпта:

  • Как таблицы склеивать будутJOIN там всякие, в каком порядке.
  • Как данные искать будут: либо тупо всю таблицу лопатить (Full Table Scan), либо по умному, через индекс (Index Scan).
  • Какие индексы в ход пойдут (если они вообще есть, конечно).
  • Сколько примерно строк на каждом этапе перелопатят.
  • Понадобятся ли временные таблицы или сортировка (Using temporary, Using filesort) — это часто признак того, что сейчас будет больно.

Давай на живом примере, а то заебали эти абстракции.

Вот есть у тебя запрос к таблице users, который выполняется дольше, чем я жду зарплату:

SELECT * FROM users WHERE email = 'test@example.com';

Ты такой: "Ну что за хуйня?". А потом пишешь перед ним EXPLAIN:

EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

И смотришь в вывод. Если там в колонке type красуется слово ALL — всё, пиши пропало, это полный перебор таблицы (Full Table Scan). База, как дура, будет честно читать каждую строчку, чтобы найти нужный email. Это и есть самое узкое место, овердохуища строк перебирать!

Что делать, гений? Да создать индекс, ёбана! Как будто оглавление в книге сделать.

CREATE INDEX idx_users_email ON users(email);

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