Все материалы
Продуктовая аналитикапрактикумсредний

EXPLAIN в PostgreSQL для аналитика: как найти медленный запрос

Понятный гайд по EXPLAIN и EXPLAIN ANALYZE: scan, join, sort, rows estimate и безопасный разбор производительности SQL.

КПКейсПрактика2 сентября 2026 г.9 мин

Запрос может быть логически корректным и всё равно тормозить дашборд. Без плана аналитик видит только время ожидания и начинает переписывать синтаксис наугад. Как понять, почему SQL работает медленно, если результат сам по себе правильный?

Рабочий вопрос

Как понять, почему SQL работает медленно, если результат сам по себе правильный?

Запрос может быть логически корректным и всё равно тормозить дашборд. Без плана аналитик видит только время ожидания и начинает переписывать синтаксис наугад.

Если planner ожидал 100 строк, а получил миллион, проблема может быть в статистике или селективности фильтра. Если сортировка ушла на диск, нужно смотреть объём, память и порядок операций.

Определение и grain

План не меняет grain результата, но помогает понять, сколько строк проходит через каждый узел. Особенно важны места, где маленький ожидаемый поток превращается в большой фактический.

Начни с логики и фильтров, затем сравни estimated rows и actual rows, найди самый дорогой узел и проверь, не изменился ли grain после JOIN. Измеряй до и после на одинаковом параметре.

Если показатель строится по событиям, отдельно проверь повторную отправку, идентичность пользователя и часовой пояс. Если данные приходят из бизнес-системы, сопоставь техническое поле с тем, как команда реально принимает решение.

Проверяемый результат
вопрос → объект → период → расчёт → проверка → решение

Любой пропущенный шаг может изменить смысл итогового числа.

Разбор примера

Если planner ожидал 100 строк, а получил миллион, проблема может быть в статистике или селективности фильтра. Если сортировка ушла на диск, нужно смотреть объём, память и порядок операций.

Не копируй пример в рабочий отчёт вслепую. Сначала замени названия таблиц и полей, проверь кардинальность связей и запиши, какие строки должны попасть в результат. Хорошая адаптация сохраняет логику, но делает допущения видимыми.

Что смотреть в плане
ПризнакВопросСледующий шаг
Rows estimateоценка близка к факту?проверить статистику
Scanчитает ли вся таблица?селективность и индекс
Sortсортировка на диске?объём и порядок данных
sqlСнять план без изменения данных
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT user_id, COUNT(*)\nFROM events\nWHERE event_at >= DATE '2026-07-01'\nGROUP BY user_id;

Где расчёт ломается

Не оптимизируй по одному запуску, не делай вывод по cost как по миллисекундам и не создавай индекс, не зная кардинальности и характера фильтров.

Отдельно протестируй пустой результат, NULL, дубль, граничную дату и объект без связанной записи. Эти случаи не являются редкими исключениями: именно они чаще всего превращают рабочий показатель в красивую, но неверную цифру.

  • Не смешивай зрелые и незрелые периоды без отдельной подписи.
  • Не заменяй проверку качества тем, что запрос просто выполнился.
  • Не делай причинный вывод из одного разреза.

Что показывает график

График здесь нужен не для украшения статьи. Он помогает увидеть форму сигнала: тренд, разрыв между сегментами, хвост распределения или этап, на котором теряется объект. Сначала прочитай оси и единицы, затем сравни с таблицей и только после этого формулируй вывод.

На визуализации «Где тратится время запроса» сравнивай не только максимальное значение. Проверь, одинаковы ли базы, не скрыта ли неполная дата и не меняется ли знаменатель от категории к категории.

Где тратится время запроса

Условный пример: один узел может объяснять большую часть времени выполнения.

Доля времени, %

Проверь на своих данных

Возьми медленный запрос с фильтром и JOIN, запиши план, назови три самых дорогих узла и сформулируй одну проверяемую гипотезу ускорения.

После упражнения напиши вывод в двух версиях. Первая — техническая: какие строки и условия дали результат. Вторая — для команды: что изменилось, насколько это надёжно и какое действие стоит проверить. Если эти версии противоречат друг другу, вернись к определению показателя.

  • Собери контрольный пример из пяти-десяти строк.
  • Сверь итог с независимым способом расчёта.
  • Проверь хотя бы один крайний случай.
  • Зафиксируй дату, версию схемы и ограничение.

Решение и продолжение

Сначала устрани неверный grain, лишние строки и позднюю фильтрацию. Индекс и переписывание запроса — следующий шаг, а не первая реакция.

Сильный аналитический материал не обещает абсолютной уверенности. Он показывает, как получить число, где оно может ошибиться и какое решение можно принять уже сейчас. Такой формат хорошо переносится в дашборд, SQL-тренажёр, собеседование и рабочее обсуждение с командой.

Продолжить чтение
Вся библиотека