ANALYZE — это команда PostgreSQL, которая собирает статистику о содержимом таблиц и индексов и сохраняет её в системный каталог pg_statistic.

Эта статистика используется планировщиком запросов для выбора оптимального плана выполнения.

Планировщик должен отвечать на вопросы:
	- Сколько строк вернёт `WHERE status = 'shipped'`?
		# Планировщик использует статистику (`pg_stats`), чтобы предсказать, **какая доля строк удовлетворяет условию**.
		# - Если `'shipped'` — 90% строк → `Seq Scan` выгоднее.
		# - Если `'shipped'` — 0.1% строк → нужен `Index Scan`.
	- Какой индекс эффективнее использовать?
		# Если по колонке есть несколько индексов (например, btree, gin, частичный), планировщик сравнивает их:
		# - Стоимость чтения,
		# - Покрывает ли индекс все нужные колонки (`index-only scan`),
		# - Насколько точно он фильтрует данные.
	- Нужно ли делать `Hash Join` или `Nested Loop`?
		# Выбор алгоритма соединения
		# Зависит от оценки числа строк в обеих таблицах:
			# - Nested Loop — хорошо, если одна таблица мала (например, 1 строка).
			# - Hash Join — эффективен при средних объёмах (тысячи–миллионы строк).
			# - Merge Join — используется, если обе таблицы уже отсортированы.
			
# Планировщик выбирает самый дешёвый (по cost) план на основе статистики.
# Если статистика устарела — оценки ошибочны → план неоптимален → запрос медленный.  
 

Как работает ANALYZE

  1. Выборка данных
  • ANALYZE не читает всю таблицу, а делает случайную выборку.
  • Размер выборки определяется параметром default_statistics_target (по умолчанию — 100).
    • Это макс. число «частей» (buckets) гистограммы на колонку.
    • Чем выше значение — тем точнее статистика, но дольше сбор.
  1. Сбор информации по каждой колонке Для каждой проанализированной колонки собирается:
Тип данныхСобираемая статистика
ЛюбойЧисло NULL’ов
Числа, датыГистограмма значений (распределение), среднее значение
Текст, UUIDНаиболее частые значения (MCV — Most Common Values) + их частота
ВсеЧисло различных значений (n_distinct)
# Пример:  
# Для колонки `status` в `orders`:
# - MCV: `'shipped' (60%)`, `'pending' (30%)`, `'cancelled' (10%)`
# - NULLs: 0
# - n_distinct: 3
  1. Сохранение в pg_statistic
  • Результат записывается в системную таблицу pg_statistic (доступна через pg_stats).
  • Эта информация автоматически используется всеми сессиями.

КомандаЭффект
ANALYZE;Анализ всех таблиц во всех БД (редко используется)
ANALYZE table_name;Анализ одной таблицы
ANALYZE table_name (col1, col2);Анализ только указанных колонок
ANALYZE VERBOSE;Показывает, что именно анализировалось

Обычно не нужно запускать вручную — этим занимается autovacuum.

  • ANALYZE не блокирует таблицу
  • VACUUM и ANALYZEнезависимые операции. Но autovacuum часто запускает их вместе.
  • При высокой селективности (WHERE id = 12345) планировщик использует другие методы (например, индексную статистику).
  • ANALYZE на временной таблице работает, но данные живут только в сессии.

Когда запускать вручную?

СценарийДействие
Массовая загрузка данных (COPY, INSERT ... SELECT)Обязательно: ANALYZE table; после загрузки
Изменение распределения данных (например, архивация старых записей)ANALYZE table;
Появились новые индексы по выражениямANALYZE table;
Запросы начали использовать плохие планыПроверить pg_stats, при необходимости — ANALYZE