advanced

Query plans

Читайте planner output, чтобы находить scans, join order, sort cost, bad cardinality estimates и missing indexes.

Query planner выбирает, как выполнить SQL: порядок join, методы доступа (index scan vs sequential scan), стратегии sort/hash и параллелизм. `EXPLAIN` (и `EXPLAIN ANALYZE`) показывает оценочную и фактическую стоимость и число строк.

					EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, u.email
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.created_at >= '2026-01-01'
ORDER BY o.created_at DESC
LIMIT 50;
				

Тревожные сигналы в планах:

| Сигнал | Часто означает | |--------|----------------| | Sequential scan на большой таблице | Нет или не используется индекс | | Nested loop с огромным outer | Плохой порядок join или статистика | | Sort / Hash на миллионах строк | Нет индекса под `ORDER BY` / ключ join | | Estimated ≠ actual rows (10×+) | Устаревшая статистика — нужен `ANALYZE` | | Bitmap heap scan + высокий recheck | Мало селективный индекс |

Читайте сверху вниз по cost hotspots; проверяйте возможность index-only scan; смотрите, применён ли фильтр рано (`Index Cond` vs `Filter`).

На интервью: для медленного endpoint опишите, как снимете план, какой узел правите первым и какой index или rewrite попробуете.

Типовые ошибки: оптимизация без `ANALYZE` после bulk load; доверие только estimated rows; добавление индексов до понимания порядка join; игнор buffer/cache в dev vs prod.

Компромисс — между формой SQL, удобной planner, и читаемостью: иногда rewrite (подзапрос в join, materialization CTE) выгоднее ещё одного индекса.

Чеклист:

  • Запустите `EXPLAIN ANALYZE` на объёме, близком к production.
  • Сравните estimated и actual row counts.
  • Найдите seq scan, sort и nested loop на больших наборах.
  • Предложите index или rewrite с ожидаемым изменением плана.
  • Перепроверьте после обновления статистики или смены схемы.