open atlas
↑ К треку
Базы данных DB · 03 · 05

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

По умолчанию планировщик предполагает независимость колонок. CREATE STATISTICS учит его функциональным зависимостям, многоколоночному n_distinct и комбинациям MCV — устраняя самый распространённый класс ошибок оценки строк.

DB Senior ◷ 14 min
Уровень
ОсновыJuniorMiddleSenior

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× на затронутых узлах.

Все четыре шага замыкают цикл: выявить разрыв оценки, отследить его до коррелированных колонок, обучить планировщика корреляции, подтвердить исправление. Без шага 4 нельзя знать, помог ли объект статистики — планировщик использует его только тогда, когда предикат точно совпадает с объявленными колонками.

Стоимость хранения: небольшая — килобайты на объект статистики. Улучшение планирования на затронутых запросах: 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×. Теперь, когда видишь промах оценки в 1000× в многоколоночном WHERE, прежде чем тянуться к хинтам или переписывать индексы — спроси себя, есть ли у этих колонок естественная иерархия. Если есть — две строки SQL исправят модель планировщика навсегда.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 5 завершено
Связанные уроки
встречается в177

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

Примени это

Примени этот урок в реальном проекте.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.