EXPLAIN: с чего начать
Введение в EXPLAIN, EXPLAIN ANALYZE и BUFFERS: чем отличаются планы и как безопасно начинать анализ запросов PostgreSQL.
PostgreSQLEXPLAINПроизводительностьЛена из поддержки аккуратно постучала в открытую дверь Макса:
— Ты обещал научить меня разбираться с тормозящими запросами. Может, начнём? А то я даже не понимаю, куда смотреть, когда пишут «у вас там план кривой».
Макс отложил кружку с остывшим кофе и убрал с экрана монитора три вкладки с алертами:
— Окей, давай по порядку. Ты видишь в логах, что «запрос выполняется 10 секунд» — это симптом болезни. А EXPLAIN — это рентген, который покажет, где конкретно проблема.
Лена нахмурилась:
— Я так понимаю, что это… инструкция, как Postgres выполняет запрос?
— Почти! — Макс развернул монитор. — Но есть нюансы.
Три вида «рентгена»
Макс открыл новое окно и быстрым движением набрал:
EXPLAIN SELECT * FROM orders WHERE order_type = 10;1. EXPLAIN — теоретический план
— Смотри, это как маршрут на бумажной карте. Postgres говорит: «Я бы сделал так», но не факт, что в реальности будет так же. Видишь Seq Scan? Это значит, он планирует читать всю таблицу подряд.
2. EXPLAIN ANALYZE — реальное выполнение
Макс добавил ANALYZE:
EXPLAIN ANALYZE SELECT * FROM orders WHERE order_type = 10;— А это уже как навигатор с пробками. Тут есть реальные цифры: сколько времени заняло, сколько строк обработано. Для простого узла actual rows=1 при rows=1000 означает ошибку оценки в тысячу раз. Если есть повторные выполнения, обязательно учитывай loops: фактические значения показываются в среднем на один цикл.
Лена кивнула:
— То есть если запрос тормозит, сначала смотрим тут?
— Да, но… — Макс ухмыльнулся. — И полезно явно запросить работу с буферами, особенно если ты читаешь план из версии до PostgreSQL 18.
3. EXPLAIN (ANALYZE, BUFFERS) — работа со страницами
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE order_type = 10;— BUFFERS покажет обращения к shared, local и temp blocks: hit, read, dirtied, written. Но read не доказывает физическое чтение с диска — страница могла находиться в кэше операционной системы. А VERBOSE добавляет структуру выходных столбцов и другие детали.
— И запомни: ANALYZE здесь означает выполнение запроса, а не сбор статистики командой ANALYZE. Для изменяющего SQL побочные эффекты реальны. Даже SELECT может быть тяжёлым, прогреть кэши и повлиять на других пользователей, поэтому продакшен требует отдельной оценки.
Практика
Макс подвинул клавиатуру:
— Давай попробуем. Напиши любой свой запрос, и сделаем к нему EXPLAIN ANALYZE.
Лена ввела что-то вроде:
SELECT count(*) FROM tasks WHERE status = 'new' AND created_at > '2025-01-01';— Ого! — она указала на цифры. — Seq Scan on tasks, а потом Filter… И он прогнал 500 тыс. строк!
— Вот и кандидат на оптимизацию, — Макс сохранил план в файл. — В следующий раз разберём, как заменить это на Index Scan.
Что запомнить
-
EXPLAIN — только план (без выполнения запроса)
-
EXPLAIN ANALYZE— выполнит запрос и покажет фактические замеры; в PostgreSQL 18 он автоматически включает сведения о буферах -
EXPLAIN (ANALYZE, BUFFERS)— явно запрашивает сведения о буферах и остаётся понятной переносимой записью для старых версий
На рабочей базе сначала получите план без выполнения и оцените риск фактического запуска. В PostgreSQL 18
ANALYZEавтоматически включаетBUFFERS; в более ранних поддерживаемых версиях его нужно было указывать отдельно.
- Сильная разница между
rowsиactual rowsуказывает на ошибку оценки; приloops > 1сравнивайте значения с учётом повторов
Лена потянулась за своим ноутбуком:
— Ладно, теперь я хотя бы понимаю, как смотреть. А что дальше?
Макс ухмыльнулся и показал на строку подключения к тестовой базе:
— Дальше — практика без теории. Просто гоняй любые запросы через EXPLAIN на тестовой базе и смотри, что получается. Не пытайся сразу всё понять — просто привыкай к структуре.
— Даже если я ничего не пойму?
— Особенно если не поймешь! — Макс подвинул ей список команд. — Записывай вопросы:
-
«Что такое Seq Scan, а что такое Index Scan?»
-
«Что значит cost=100500?»
-
«Почему Actual Rows меньше, чем Rows?»
Вопросы присылай — разберём. Главное — перестать бояться этих «иероглифов».
— Окей, попробую. Но если я сломаю тестовую базу…
— Если сломаешь — значит, учишься, — Макс допил кофе. — До завтра!
Практическое задание
Попробуйте прямо сейчас сделать EXPLAIN любого вашего запроса в тестовой базе. Не ищите ответы — просто фиксируйте, что кажется странным.