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