pg_plan_advice, которое добавит пользовательские хинты. Но как Postgres столько лет обходился без хинтов, пока другие СУБД на них опирались? Статистика.Начиная с 1998 года, Postgres использует статистику на уровне колонок для генерации планов запросов. Алгоритм много раз улучшался и давно считается хорошо проверенной системой выбора плана выполнения на основе статистики. Статистика, которую генерирует
ANALYZE, — основа планировщика запросов.Когда вы запускаете
ANALYZE, Postgres строит две структуры для каждой колонки. Именно на них в первую очередь смотрит планировщик, когда оценивает, сколько строк вернёт WHERE.Ниже примеры из таблицы с HTTP-запросами. Такой набор данных удобно использовать, потому что там есть разные типы значений, которые легко представить.
Список наиболее частых значений (MCV)
Если самая сложная задача в компьютерных науках — кеширование и нейминг, то список most common values заслуживает место в зале славы за удачное название.
Это самые частые значения колонки и их точные частоты:
most_common_vals = {GET, POST, PUT, DELETE, PATCH}
most_common_freqs = {0.70, 0.20, 0.05, 0.03, 0.02}Здесь это HTTP-методы, поэтому набор значений ограничен спецификацией.
Для
WHERE method = 'GET' планировщик напрямую читает 0.70 из списка.70% от 200 000 строк = ожидаемые 140 000 строк.
Гистограмма с бакетами равной высоты
Для значений, которых нет в MCV-списке, Postgres строит equi-height buckets. Ниже пример гистограммы для колонки со временем ответа в миллисекундах:
histogram_bounds = {83, 88, 95, 107, 132, 166, 195, 245, 362, 554, 965, 2622164}Каждый бакет содержит примерно одинаковое количество строк. Бакет
[245, 362] содержит примерно столько же строк, сколько [83, 88].За счёт фиксированного количества строк диапазон значений становится переменным. Это упрощает оценку количества строк.
NULL-гистограммы
Когда все уникальные значения помещаются в MCV-список,
histogram_bounds становится NULL.У колонки
method всего 5 значений. Все они попадают в MCV-список, поэтому гистограмма не нужна.Зачем нужны две структуры?
MCV даёт точные частоты для популярных значений, а гистограмма покрывает длинный хвост — редкие или непрерывные значения через приближение. Вместе они описывают полное распределение без хранения каждого значения отдельно.
Чтобы посмотреть статистику для таблицы и колонки:
SELECT
most_common_vals,
most_common_freqs,
histogram_bounds
FROM pg_stats
WHERE tablename = 'requests'
AND attname = 'status_code';
👉 @SQLPortal

