Что такое EXPLAIN
EXPLAIN — это команда, которая показывает план выполнения запроса без его реального выполнения (в большинстве СУБД). Она отвечает на вопрос: какие шаги планировщик запросов выбрал для получения результата.
В ответе обычно видно:
тип доступа к таблице: Seq Scan, Index Scan, Bitmap Heap Scan, Nested Loop, Hash Join, Merge Join;
какой индекс используется, если используется вообще;
оценку количества строк (rows) и стоимости (cost);
порядок операций: сначала нижние узлы дерева, потом верхние.
Что такое EXPLAIN ANALYZE
EXPLAIN ANALYZE идёт дальше: запрос реально выполняется, и к плану добавляются фактические метрики — сколько строк вернул каждый узел, сколько времени занял, насколько оценка планировщика совпала с реальностью.
Это особенно полезно, когда нужно понять, почему запрос медленный на практике: планировщик мог выбрать индекс, который в реальности даёт мало пользы, или сильно ошибиться в оценке селективности.
Как читать план запроса
Смотрите на самый дорогой узел — обычно именно он съедает большую часть времени: например, полный скан таблицы (Seq Scan) или тяжёлый Join.
Понимайте иерархию — план читается снизу вверх: дочерние узлы отдают данные родительскому узлу.
Сравнивайте estimate и actual — если планировщик ожидал 100 строк, а реально пришло 100 000, значит статистика устарела или условия плохо оцениваются.
Проверяйте доступ к таблицам — если вместо Index Scan видите Seq Scan, возможно, индекс не подходит, условие не sargable или данных слишком много для индекса.
Смотрите на join strategy — Nested Loop хорош для маленьких наборов, Hash Join — для больших, Merge Join — когда данные уже отсортированы или сортировка дешёвая.
Что обычно означает плохой план
полное сканирование большой таблицы там, где ожидался поиск по индексу;
большое расхождение между rows и фактическим числом строк;
слишком дорогой Nested Loop на больших объёмах;
лишние сортировки, хеширования и пересылки данных между узлами плана.
Как улучшать запрос по плану
добавить или изменить индекс, если фильтрация и сортировка часто идут по одним и тем же полям;
переписать запрос так, чтобы он лучше использовал индекс;
обновить статистику (ANALYZE / VACUUM ANALYZE в PostgreSQL);
уменьшить объём данных до тяжёлых JOIN или агрегаций, предварительно отфильтровав строки.
Как ответить на собеседовании
EXPLAIN показывает план запроса, а EXPLAIN ANALYZE показывает ещё и фактическое выполнение. Я читаю план сверху вниз как дерево операций, смотрю на самые дорогие узлы, сравниваю оценку планировщика с реальными числами и проверяю, использует ли запрос индекс или уходит в полный скан. Если план плохой, обычно начинаю с индекса, статистики и переписывания самого запроса.