Что делает команда `EXPLAIN ANALYZE` в PostgreSQL и чем она отличается от `EXPLAIN`?

Ответ

Это ключевые команды для анализа и оптимизации производительности запросов в PostgreSQL.

EXPLAIN

Команда EXPLAIN не выполняет сам запрос. Она обращается к планировщику PostgreSQL и показывает предполагаемый (гипотетический) план выполнения запроса. Этот план строится на основе статистики о таблицах, которую собрал ANALYZE (или автовакуум).

Что показывает:

  • Последовательность операций (Scan, Join, Sort, Aggregate).
  • Оценочную стоимость (cost) начала выполнения и общую стоимость.
  • Оценочное количество строк (rows), которое вернёт каждая операция.

EXPLAIN ANALYZE

Эта команда делает всё то же, что и EXPLAIN, но с одним важным отличием: она реально выполняет запрос. Поэтому её вывод содержит не только предполагаемый план, но и фактические метрики выполнения.

Что добавляется к выводу EXPLAIN:

  • actual time: Реальное время в миллисекундах, затраченное на выполнение операции (от старта первой строки до получения последней).
  • rows: Фактическое количество строк, возвращённое операцией.
  • loops: Сколько раз выполнялся данный узел плана.
  • Buffers: Информация об использовании буферного кэша (shared-памяти). hit означает, что блок данных был найден в кэше, read — что он был прочитан с диска.

Пример вывода:

-- План с реальными метриками
EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;

-- Результат
Index Scan using users_pkey on users (cost=0.29..8.31 rows=1 width=118) 
  (actual time=0.025..0.026 rows=1 loops=1)
  Index Cond: (id = 1)
  Buffers: shared hit=4

Ключевое отличие:

  • EXPLAIN — быстро и безопасно, показывает намерения планировщика. Используется для быстрой оценки плана.
  • EXPLAIN ANALYZE — медленнее (т.к. выполняет запрос) и может быть опасно для UPDATE/DELETE/INSERT на продуктивной базе. Показывает реальную картину и помогает найти узкие места, где оценка планировщика сильно разошлась с реальностью.

Ответ 18+ 🔞

А, ну это же про ту самую магию, когда твой запрос ползёт как черепаха в сиропе, а ты сидишь и думаешь: "Ну что за хуйня?". Так вот, слушай сюда, сейчас разжую.

Есть у нас две волшебные палочки. Первая — EXPLAIN. Это как посмотреть на карту маршрута, не выходя из дома. Запрос НЕ выполняется, блядь, вообще! Планировщик, этот хитрожопый теоретик, на основе своей статистики (которую собрал ANALYZE) рисует тебе план: "Ага, мол, сначала вот тут посмотрим, потом присоединим вот это, отсортируем, и будет вам счастье, примерно за 5 условных копеек".

Показывает он:

  • Что и в каком порядке будет делаться (сканирование, джойны, сортировка).
  • Предполагаемую стоимость (cost) — начало и конец.
  • Предполагаемое число строк (rows), которое каждая операция должна выплюнуть.

А теперь вторая палочка, посерьёзнее — EXPLAIN ANALYZE. Это уже не теория, ёпта, это боевые учения с реальными выстрелами. Команда берёт и на самом деле выполняет твой запрос, внатуре! Поэтому, если ты её запустишь на продакшене на каком-нибудь DELETE FROM huge_table, можешь потом идти пить чай. Надолго.

Но зато она показывает не только план, а как всё было на самом деле:

  • actual time: Реальное время в миллисекундах, за которое операция отстрелялась (от первой строки до последней).
  • rows: Фактическое, блядь, количество строк, а не те фантазии планировщика.
  • loops: Сколько раз эту операцию пришлось повторять.
  • Buffers: Вот это вообще золото! Показывает, как работала память. hit — данные были в кэше (ура!), read — пришлось лезть на медленный диск (пиздец).

Смотри, как это выглядит в жизни:

-- Спрашиваем у системы: "Ну как, справишься?"
EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;

-- А система отвечает:
Index Scan using users_pkey on users (cost=0.29..8.31 rows=1 width=118)
  (actual time=0.025..0.026 rows=1 loops=1) -- О, смотри, оценка и реальность почти сошлись! Красота.
  Index Cond: (id = 1)
  Buffers: shared hit=4 -- И всё из кэша взяли, вообще огонь!

Так в чём же, блядь, разница, спросишь ты? А разница проще пареной репы:

  • EXPLAIN — это быстро и безопасно. Как глянуть в гороскоп на день. "Планировщик намекает, что будет вот так". Используешь для быстрой прикидки.
  • EXPLAIN ANALYZE — это уже разбор полётов после реального вылета. Медленнее, может быть опасно на проде, но показывает, где конкретно твой запрос обосрался. Особенно когда в плане rows=1000, а actual rows=1000000. Вот тут-то и начинается самое интересное, ебать мои старые костыли!