14.2. Статистика, используемая планировщиком
Как было показано в предыдущем разделе, планировщик запросов должен оценить число строк, возвращаемых запросов, чтобы сделать правильный выбор в отношении плана запроса. В этом разделе кратко описывается статистика, которую использует система для этих оценок.
В частности, статистика включает общее число записей в каждой таблице и индексе, а также число дисковых блоков, которые они занимают. Эта информация содержится в таблице pg_class
, в столбцах reltuples
и relpages
. Получить её можно, например так:
SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%'; relname | relkind | reltuples | relpages ----------------------+---------+-----------+---------- tenk1 | r | 10000 | 358 tenk1_hundred | i | 10000 | 30 tenk1_thous_tenthous | i | 10000 | 30 tenk1_unique1 | i | 10000 | 30 tenk1_unique2 | i | 10000 | 30 (5 rows)
Здесь мы видим, что tenk1
содержит 10000 строк данных и столько же строк в индексах (что неудивительно), но объём индексов гораздо меньше таблицы.
Для большей эффективности reltuples
и relpages
не пересчитываются «на лету», так что они обычно содержат несколько устаревшие значения. Их обновляют команды VACUUM
, ANALYZE
и несколько команд DDL, такие как CREATE INDEX
. VACUUM
и ANALYZE
могут не сканировать всю таблицу (и обычно так и делают), а только вычислить приращение reltuples
по части таблицы, так что результат остаётся приблизительным. В любом случае планировщик пересчитывает значения, полученные из pg_class
, в пропорции к текущему физическому размеру таблицы и таким образом уточняет приближение.
Большинство запросов возвращают не все строки таблицы, а только немногие из них, ограниченные условиями WHERE
. Поэтому планировщику нужно оценить избирательность условий WHERE
, то есть определить, какой процент строк будет соответствовать каждому условию в предложении WHERE
. Нужная для этого информация хранится в системном каталоге pg_statistic
. Значения в pg_statistic
обновляются командами ANALYZE
и VACUUM ANALYZE
и никогда не бывают точными, даже сразу после обновления.
Для исследования статистики лучше обращаться не непосредственно к таблице pg_statistic
, а к представлению pg_stats
, предназначенному для облегчения восприятия этой информации. Кроме того, представление pg_stats
доступно для чтения всем, тогда как pg_statistic
— только суперпользователям. (Это сделано для того, чтобы непривилегированные пользователи не могли ничего узнать о содержимом таблиц других людей из статистики. Представление pg_stats
устроено так, что оно показывает строки только для тех таблиц, которые может читать данный пользователь.) Например, мы можем выполнить:
SELECT attname, inherited, n_distinct, array_to_string(most_common_vals, E'\n') as most_common_vals FROM pg_stats WHERE tablename = 'road'; attname | inherited | n_distinct | most_common_vals ---------+-----------+------------+------------------------------------ name | f | -0.363388 | I- 580 Ramp+ | | | I- 880 Ramp+ | | | Sp Railroad + | | | I- 580 + | | | I- 680 Ramp name | t | -0.284859 | I- 880 Ramp+ | | | I- 580 Ramp+ | | | I- 680 Ramp+ | | | I- 580 + | | | State Hwy 13 Ramp (2 rows)
Заметьте, что для одного столбца показываются две строки: одна соответствует полной иерархии наследования, построенной для таблицы road
(inherited
=t
), и другая относится непосредственно к таблице road
(inherited
=f
).
Объём информации, сохраняемой в pg_statistic
командой ANALYZE
, в частности максимальное число записей в массивах most_common_vals
(самые популярные значения) и histogram_bounds
(границы гистограмм) для каждого столбца, можно ограничить на уровне столбцов с помощью команды ALTER TABLE SET STATISTICS
или глобально, установив параметр конфигурации default_statistics_target. В настоящее время ограничение по умолчанию равно 100 записям. Увеличивая этот предел, можно увеличить точность оценок планировщика, особенно для столбцов с нерегулярным распределением данных, ценой большего объёма pg_statistic
и, возможно, увеличения времени расчёта этой статистики. И напротив, для столбцов с простым распределением данных может быть достаточно меньшего предела.
Подробнее использование статистики планировщиком описывается в Главе 67.