awesome-everything EN
↑ Обратно к восхождению

Базы данных

Расширенная статистика: исправление ошибок оценки для коррелированных колонок

Суть По умолчанию планировщик предполагает независимость колонок. CREATE STATISTICS учит его функциональным зависимостям, многоколоночному n_distinct и комбинациям MCV — устраняя самый распространённый класс ошибок оценки строк.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

WHERE-условие фильтрует по country='US' AND region='CA' AND status='shipped'. Планировщик предсказывает 500 совпадающих строк — три независимые вероятности, перемноженные вместе. Реальных строк 50,000. Nested Loop выполняется в 100× лишних раз. Колонки коррелированы, а не независимы. CREATE STATISTICS исправляет это двумя строками SQL.

Почему предположение о независимости ломается

Дефолтная модель многоколоночной селективности планировщика:

P(country='US' AND region='CA' AND status='shipped')
  = P(country='US') × P(region='CA') × P(status='shipped')
  = 0.50 × 0.05 × 0.20
  = 0.005 (0.5%)

Но если country определяет region (каждый CA-заказ в US — функциональная зависимость), реальная селективность:

P(region='CA') × P(status='shipped') = 0.05 × 0.20 = 1.0%

На 100M строках: планировщик оценивает 500,000 строк; реальность — 1,000,000 — ошибка в 2×, которая может склонить Nested Loop к катастрофическому поведению. При более жёстких корреляциях ошибка может быть в 1000×.

Три вида расширенной статистики

CREATE STATISTICS (доступен с PG 10) поддерживает три взаимодополняющих вида:

ВидЧто хранитИсправляетС версии
dependenciesКоэффициенты функциональной зависимости между парами колонокОдна колонка подразумевает другую (zip → city, country → region)PG 10
ndistinctСчётчик уникальных комбинаций для многоколоночных группКардинальность GROUP BY по нескольким колонкамPG 10
mcvНаиболее часто встречающиеся кортежи значений для комбинации колонокТочные оценки для частых комбинацийPG 12

dependencies

Хранит коэффициенты функциональной зависимости между парами колонок. Коэффициент, близкий к 1.0, означает «колонка A почти всегда определяет колонку B». Когда планировщик видит WHERE country='US' AND region='CA', он проверяет зависимость между country и region — если country определяет region с коэффициентом 0.95, планировщик знает, что не нужно перемножать P(country) × P(region); вместо этого он оценивает на основе более селективной из двух.

CREATE STATISTICS stx_orders_geo (dependencies)
  ON country, region, status FROM orders;
ANALYZE orders;

ndistinct

Без этого планировщик оценивает количество уникальных комбинаций (country, region) как n_distinct(country) × n_distinct(region), что резко переоценивает, когда колонки коррелированы. ndistinct хранит реальное количество комбинаций.

Полезно для запросов вида:

SELECT country, region, COUNT(*) FROM orders GROUP BY country, region;

Без ndistinct планировщик может выделить Hash Aggregate, ожидая миллионы групп, тогда как их сотни.

mcv (многоколоночные наиболее частые значения)

Хранит наиболее частые кортежи комбинации колонок напрямую — аналог MCV-списка на уровне колонки, но для пар или троек. Для WHERE country='US' AND status='shipped', если (US, shipped) — частая комбинация, планировщик читает её точную частоту из MCV-списка, а не перемножает маргинальные вероятности.

Доступен с PG 12 и часто является наиболее ценным видом для OLTP-шаблонов запросов.

Статистика выражений (PG 14+)

PG 14 добавил статистику по выражениям:

CREATE STATISTICS stx_orders_lower_email ON LOWER(email) FROM users;
ANALYZE users;

Это позволяет планировщику точно оценивать селективность для WHERE LOWER(email) = 'x' даже без функционального индекса на LOWER(email).

Когда и как применять CREATE STATISTICS

Рабочий процесс:

  1. Запустите EXPLAIN ANALYZE на медленном запросе. Найдите узлы, где rows (оценка) отличается от actual rows более чем в 10×.
  2. Определите колонки WHERE на этом узле. Проверьте, коррелированы ли они: zip и city, country и region, продукт и категория.
  3. Создайте объект статистики:
-- Наиболее частый шаблон: dependencies + mcv вместе
CREATE STATISTICS stx_orders_country_region_status
  (dependencies, mcv)
  ON country, region, status FROM orders;

-- Для точности GROUP BY:
CREATE STATISTICS stx_orders_ndistinct
  (ndistinct)
  ON country, region FROM orders;

-- Запустите ANALYZE для заполнения:
ANALYZE orders;
  1. Повторно запустите EXPLAIN ANALYZE. Убедитесь, что rows отслеживает actual rows в пределах 2× на затронутых узлах.

Стоимость хранения: небольшая — килобайты на объект статистики. Улучшение планирования на затронутых запросах: 100–1000×.

Почему это работает

Почему default_statistics_target не решает эту проблему? Повышение целевого значения (например, до 1000) даёт более детальные гистограммы и более длинные MCV-списки для отдельных колонок — но не учит планировщика корреляциям между колонками. С MCV-списками из 1000 записей планировщик всё равно перемножает P(country) × P(region) — просто с лучшими одноколоночными оценками. Предположение о независимости сохраняется. CREATE STATISTICS заменяет предположение о независимости для конкретных групп колонок; SET STATISTICS уточняет данные, используемые внутри него.

Викторина

Какой инструмент правильный, чтобы сообщить планировщику о корреляции двух колонок (например, zip и city)?

Викторина

Когда `ndistinct` является правильным видом расширенной статистики для создания?

Викторина

После запуска CREATE STATISTICS на (country, region, status) и ANALYZE, как убедиться, что статистика реально улучшила оценку?

Вспомните перед уходом
  1. 01
    Объясните провал предположения о независимости и почему CREATE STATISTICS (dependencies) исправляет его.
  2. 02
    В чём разница между 'dependencies', 'mcv' и 'ndistinct' в CREATE STATISTICS?
  3. 03
    Как определить, какие комбинации колонок нуждаются в расширенной статистике в production базе данных?
Итог

По умолчанию планировщик перемножает одноколоночные селективности, предполагая независимость — крайне неверно для коррелированных колонок вроде (country, region) или (zip, city). CREATE STATISTICS добавляет три вида многоколоночной информации: dependencies (коэффициенты функциональной зависимости между парами колонок, исправляя ошибки оценки для WHERE A=‘x’ AND B=‘y’ когда A определяет B), ndistinct (реальное количество комбинаций для точной кардинальности GROUP BY) и mcv (кортежи наиболее частых значений для частых конкретных комбинаций, доступен с PG 12). PG 14+ добавил статистику выражений. Стоимость хранения — килобайты; улучшение планирования на затронутых запросах — 100–1000×. После создания статистики всегда запускайте ANALYZE и проверяйте с EXPLAIN ANALYZE, что rows-estimated отслеживает rows-actual в пределах 2× на затронутых узлах.

Практика

Сделай это, чтобы превратить узнавание в навык.

Связанные уроки
встречается в174
Продолжить восхождение ↑Кеш планов, настройка константных стоимостей и внутренности планировщика
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.