Как читать план запроса
Как читать план запроса¶
План запроса — это карта того, как СУБД реально выполняет твой SQL. Не как «в теории», а как конкретно: чем читает, как соединяет, где сортирует и где тратит время.
Как посмотреть план¶
Добавь EXPLAIN перед запросом:
Самые полезные варианты:
EXPLAIN— показывает оценку (cost/rows/width).EXPLAIN ANALYZE— выполняет запрос и показывает фактическое время/строки.EXPLAIN (ANALYZE, BUFFERS, VERBOSE)— плюс буферы и расширенные детали.
Простая аналогия
EXPLAIN — это когда ты читаешь рецепт и думаешь, что все получится. EXPLAIN ANALYZE — когда ты реально готовишь и понимаешь, что духовки нет.
Осторожно на проде
EXPLAIN ANALYZE реально выполняет запрос. На тяжелых выборках может быть больно.
Что ты увидишь внутри¶
План — это дерево узлов. Каждый узел отвечает за конкретную операцию:
- Scan — как читаем (Seq / Index / Bitmap).
- Join — как соединяем (Hash / Merge / Nested Loop).
- Sort / Aggregate / Window — сортировки, агрегации, окна.
- Motion — только в MPP/Greenplum (Gather / Redistribute / Broadcast).
- Spill to disk — сброс на диск, если памяти не хватило на sort/hash.
Главное, на что смотреть¶
- actual time — где реально тратится время.
- rows (estimated vs actual) — если различие сильное, проблемы со статистикой.
- Join-стратегии — Nested Loop на больших объемах часто беда.
- Sort / Hash — были ли спиллы на диск (workfiles).
- Motion в GP — узкие места и перекладывание данных между сегментами.
Быстрая шпаргалка по метрикам¶
- cost — не миллисекунды, а абстрактные единицы оптимизатора.
- rows — сколько строк ожидается и сколько получилось.
- width — средний размер строки.
- actual time — реальные времена выполнения.
- buffers — попадания в кэш и чтения с диска.
Мини-пример¶
Запрос:
EXPLAIN (ANALYZE, BUFFERS)
SELECT region, sum(amount)
FROM sales
WHERE amount > 100
GROUP BY region;
Фрагмент плана (упрощенно):
HashAggregate (cost=... rows=...) (actual time=... rows=...)
-> Seq Scan on sales (cost=... rows=...) (actual time=... rows=...)
Filter: (amount > 100)
Как читать: - Сначала читаем таблицу (Seq Scan) и фильтруем строки. - Потом агрегируем по region (HashAggregate).
Что я рекомендую¶
- Серия статей по PG (Tensor): https://habr.com/ru/companies/tensor/articles/790282/
- Репозиторий с материалами: https://github.com/Kilor/PG-for-beginners/tree/main
- Интерактивные планы: https://explain.tensor.ru/archive/
- Можно использовать ИИ для объяснений — но выводы перепроверяй.
Что дальше¶
В отдельном разборе пройдемся по реальному плану GP/PG: где теряется время, как найти узкие места и чем лечить.