Исходная страница в нативном Markdown: Статистика / Расширенная статистика
Примечание
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета.
HTML source:qpt_12_stats_extended.htmlArchive:QPT-handouts-16.zipСтраниц PDF: 19
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
Функциональная зависимость
Наиболее частые комбинации значений
Число уникальных комбинаций значений
Статистика по выражениям
Page 3: Расширенная статистика
Включает
многовариантную статистику (по нескольким столбцам)
статистику по выражениям
Объект базы данных, создается вручную
хранится в pg_statistic_ext и pg_statistic_ext_data
представления pg_stats_ext и pg_stats_ext_exprs
После создания статистика собирается автоматически
Комментарии преподавателя
Базовой статистики, которая собирается автоматически, может не хватать для точных оценок кардинальности и селективности.
PostgreSQL позволяет администратору вручную определить, какая дополнительная — расширенная — статистика требуется. Можно собрать статистику, охватывающую не один столбец, а сразу несколько (многовариантная статистика), или статистику по произвольному выражению.
Заметьте, что базовая статистика собирается для таблиц и их столбцов, но не для индексов (за исключением индексов по выражениям). Поэтому и индекс, построенный по нескольким столбцам, не приводит сам по себе к появлению многовариантной статистики.
Расширенная статистика создается командой CREATE STATISTICS. После того, как объект создан, соответствующая статистика будет собираться автоматически в фоновом режиме или командой ANALYZE.
Собранная информация хранится в таблицах pg_statistic_ext и pg_statistic_ext_data; доступная пользователю статистика отображается в представлениях pg_stats_ext и pg_stats_ext_exprs.
значение одного столбца определяет значение другого столбца
статистика улучшает оценку селективности условий
Комментарии преподавателя
Существует несколько видов многовариантной статистики (то есть статистики по нескольким столбцам таблицы), которые можно указать при создании объекта расширенной статистики.
Функциональная зависимость между столбцами показывает, насколько данные в одном столбце определяются значением другого столбца.
В примере на слайде почтовый индекс однозначно определяет город, поэтому селективность условия city = ‘Самара’ and index = ‘443000’ определяется селективностью предиката index = ‘443000’. Такие предикаты, селективность которых нельзя рассчитывать отдельно друг от друга, называются коррелированными.
QUERY PLAN
------------------------------------------------------------------------------------------
-----------------
Bitmap Heap Scan on flights (cost=12.18..1277.67 rows=27 width=63)
Recheck Cond: (flight_no = 'PG0007'::bpchar)
Filter: (departure_airport = 'VKO'::bpchar)
-> Bitmap Index Scan on flights_flight_no_scheduled_departure_key (cost=0.00..12.18
rows=501 width=0)
Index Cond: (flight_no = 'PG0007'::bpchar)
(5 rows)
Причина в том, что планировщик полагается на независимость предикатов и считает итоговую селективность как произведение селективностей предикатов. Это хорошо видно в приведенном плане: оценка в узле Bitmap Index Scan (условие на flight_no) верная, а после фильтрации в узле Bitmap Heap Scan (условие на departure_airport) — заниженная.
Однако мы понимаем, что номер рейса однозначно определяет аэропорт отправления: фактически, второе условие избыточно (конечно, считая, что аэропорт указан правильно).
Это можно объяснить планировщику с помощью статистики по функциональной зависимости:
как pg_stats.most_common_vals/freqs, но для нескольких столбцов
статистика улучшает оценку селективности условий
Комментарии преподавателя
Список наиболее частых комбинаций значений позволяет сохранить несколько комбинаций значений и их частоту.
На слайде показаны возможные пары город — река. Очевидно, что предикаты со столбцами city и river коррелированы, но, в отличие от предыдущего примера, ни один из этих столбцов не определяет другой (между городами и реками отношение «многие ко многим»). В этом случае статистика по функциональным зависимостям не поможет улучшить оценки.
QUERY PLAN
-----------------------------------------------------------------------------------------
Seq Scan on flights (cost=0.00..5847.00 rows=5169 width=63) (actual rows=5148 loops=1)
Filter: ((departure_airport = 'LED'::bpchar) AND (aircraft_code = '321'::bpchar))
Rows Removed by Filter: 209719
(3 rows)
Оценка кардинальности еще немного улучшилась.
Однако это не привело к дальнейшему улучшению плана, поэтому увеличение ориентира статистики в данном случае вряд ли оправдано.
Статистику по наиболее частым комбинациям можно посмотреть так:
как pg_stats.ndistinct, но для нескольких столбцов
статистика улучшает оценку кардинальности для группировки
Комментарии преподавателя
Число уникальных комбинаций значений позволяет улучшить оценку кардинальности при группировке по нескольким столбцам.
В примере на слайде число возможных комбинаций всех полей, очевидно, нельзя определить, просто перемножив количество уникальных значений для каждого столбца по отдельности.
Отображается наличие статистики по типам (Ndistinct, Dependencies, MCV), а значения нужно смотреть в таблице pg_statistic_ext_data.
Page 13: Статистика по выражению
{#source-figure-013 caption=“Source slide page 13: Статистика по выражению”}
Расширенная статистика по выражению
как если бы в таблице был определен генерируемый столбец
статистика улучшает оценку селективности условий с выражениями
Комментарии преподавателя
Расширенная статистика по выражению позволяет собрать всю базовую статистику, которая была бы собрана, если бы в таблице был определен столбец, вычисляемый по этому выражению.
Если в предикате слева или справа от оператора стоит не имя столбца, а выражение, планировщик использует фиксированную оценку селективности. С помощью статистики по выражению это можно исправить.
Заметим, что выражения также можно использовать вместо имен столбцов в многовариантной статистике любого типа.
Page 14: Статистика по выражению
Как мы видели в теме «Базовая статистика», если в условии используются выражение, планировщик, не имея информации о селективности, использует константу и часто ошибается:
В теме «Базовая статистика» мы исправляли ситуацию, построив индекс по выражению, но это возможно не во всех случаях. К тому же индексы требуют ресурсов для хранения и постоянной синхронизации. Можно поступить иначе — добавить расширенную статистику по выражению:
Используя команды из демонстрации, создайте статистики типа dependencies, mcv и ndistinct для таблицы flights. Измерьте время выполнения команды ANALYZE. Удалите расширенные статистики, снова измерьте время выполнения команды ANALYZE и сравните с предыдущим результатом. 2. Напишите запрос, выбирающий все перелеты в бизнес-классе стоимостью более 100 тыс. рублей. Поможет ли расширенная статистика улучшить оценку кардинальности результата? Если да, то какой тип статистики лучше использовать?
Комментарии преподавателя
Выполняйте измерение времени несколько раз и усредняйте результаты, чтобы сгладить неравномерности.
Page 17: 1. Затраты на анализ
Создадим расширенные статистики аналогично тому, как это было сделано в демонстрации.
Статистика по функциональной зависимости:
В первый раз анализ может занимать существенно больше времени, чем обычно.
=> ANALYZE flights;
ANALYZE
Time: 680,730 ms
=> ANALYZE flights;
ANALYZE
Time: 620,083 ms
=> \timing off
Timing is off.
Удалим созданные расширенные статистики:
=>DROPSTATISTICSflights_dep;
DROPSTATISTICS
=>DROPSTATISTICSflights_mcv;
DROPSTATISTICS
=>DROPSTATISTICSflights_nd;
DROPSTATISTICS
Повторно измеряем время:
=> \timing on
Timing is on.
=> ANALYZE flights;
ANALYZE
Time: 385,839 ms
=> ANALYZE flights;
ANALYZE
Time: 415,945 ms
=> \timing off
Page 18: 2. Применение расширенной статистики
Timing is off.
Было создано всего три расширенные статистики, но время анализа до и после удаления заметно различается. С увеличением количества собираемых расширенных статистик будет расти и время на анализ, что может привести к увеличению нагрузки на сервер.
Поэтому использовать расширенную статистику нужно осмысленно и только в тех случаях, когда это необходимо.
Перелеты в бизнес-классе стоимостью свыше 100 тысяч ₽:
Оптимизатор ошибается на порядок. Причина в том, что стоимость билета и класс обслуживания коррелируют между собой, поэтому расширенная статистика должна помочь исправить оценку. Поскольку между столбцами нет прямой функциональной зависимости, добавим статистику по наиболее частым значениям:
QUERY PLAN
------------------------------------------------------------------------------------------
-------
Gather (cost=1000.00..126555.45 rows=31727 width=32)
Workers Planned: 2
-> Parallel Seq Scan on ticket_flights (cost=0.00..122382.75 rows=13220 width=32)
Filter: ((amount > '100000'::numeric) AND ((fare_conditions)::text =
'Business'::text))
(4 rows)
Оценка немного улучшилась, но все еще сильно отличается от точного значения. Можно заметить, что доля строк, удовлетворяющих условию, немногим более 1%:
Поскольку по умолчанию хранится 100 наиболее частых пар, среди них с большой вероятностью встретится не более 1–2 удовлетворяющих условию, и из-за этого оценка оптимизатора не будет адекватной. Попробуем повысить точность, увеличив объем статистики: