G.3. pgpro_multiplan — сохранение планов выполнения запросов для последующего использования #
- G.3.1. Описание
- G.3.2. Установка
- G.3.3. Поддерживаемые режимы и типы планов
- G.3.4. Использование замороженных планов
- G.3.5. Использование базовых планов
- G.3.6. Резервные копии замороженных планов
- G.3.7. Совместимость с другими расширениями
- G.3.8. Идентификация запросов
- G.3.9. Автоматическое приведение типов
- G.3.10. Интеграция с перепланированием запросов в реальном времени
- G.3.11. Статистика
- G.3.12. Представления
- G.3.13. Функции
- G.3.14. Параметры конфигурации
- G.3.2. Установка
G.3.1. Описание #
Расширение pgpro_multiplan позволяет сохранять планы выполнения запросов и использовать эти планы при последующем выполнении тех же запросов, что помогает избежать повторной оптимизации идентичных запросов. Можно также использовать это расширение для фиксации определённого плана выполнения, если план, выбранный планировщиком, по каким-то причинам вам не подходит.
pgpro_multiplan работает подобно Oracle SQL Plan Management.
G.3.2. Установка #
Расширение pgpro_multiplan
предоставляется вместе с Postgres Pro Enterprise в виде отдельного пакета pgpro-multiplan-ent-16
(подробные инструкции по установке приведены в Главе 17). Чтобы включить pgpro_multiplan
, выполните следующие действия:
Добавьте имя библиотеки в переменную
shared_preload_libraries
в файлеpostgresql.conf
:shared_preload_libraries = 'pgpro_multiplan'
Обратите внимание, что имена библиотек в переменной
shared_preload_libraries
должны добавляться в определённом порядке. Совместимость pgpro_multiplan с другими расширениями описана в Подразделе G.3.7.Перезагрузите сервер баз данных, чтобы изменения вступили в силу.
Чтобы убедиться, что библиотека
pgpro_multiplan
установлена правильно, вы можете выполнить следующую команду:SHOW shared_preload_libraries;
Создайте расширение pgpro_multiplan, выполнив следующий запрос:
CREATE EXTENSION pgpro_multiplan;
Расширение pgpro_multiplan использует кеш разделяемой памяти, который инициализируется только при запуске сервера, поэтому данная библиотека также должна предзагружаться при запуске. Расширение pgpro_multiplan следует создать в каждой базе данных, где требуется управление запросами.
Включите расширение pgpro_multiplan, которое выключено по умолчанию. Для этого укажите необходимые режимы в параметре pgpro_multiplan.mode. За дополнительной информацией обратитесь к разделу Поддерживаемые режимы и типы планов.
Включить pgpro_multiplan можно одним из следующих способов:
Чтобы активировать расширение для всех серверов, задайте параметр
pgpro_multiplan.mode
в файлеpostgresql.conf
.Чтобы активировать расширение в текущем сеансе, используйте следующую команду:
SET pgpro_multiplan.mode = 'frozen';
При необходимости переноса данных pgpro_multiplan с главного на резервный сервер при помощи физической репликации, на обоих серверах необходимо задать значение параметра pgpro_multiplan.wal_rw=
on
. Также убедитесь, что на обоих серверах установлена одинаковая версия pgpro_multiplan, иначе репликация может работать некорректно.
G.3.3. Поддерживаемые режимы и типы планов #
Расширение pgpro_multiplan поддерживает следующие планы:
Замороженные планы: зафиксированные планы, которым отдаётся приоритет при выполнении соответствующих запросов. Запрос может иметь только один замороженный план. pgpro_multiplan поддерживает следующие типы замороженных планов:
serialized
: сериализованное представление плана. Этот план конвертируется в выполняемый план при первом нахождении соответствующего запроса. Сериализованные планы остаются действительными до тех пор, пока не изменятся метаданные запроса (структуры таблиц, индексы и так далее). Например, если таблица, на которую ссылается замороженный план, будет пересоздана, этот план станет недействительным и будет игнорироваться. Сериализованные планы действительны только в текущей базе данных и не могут быть скопированы в другую, поскольку зависят от идентификаторов объектов (OID). По этой причине использовать сериализованные планы для временных таблиц не имеет смысла.hintset
: набор указаний, формируемый на основе плана выполнения в момент заморозки. Этот набор включает значения переменных окружения оптимизатора, отличных от используемых по умолчанию, типы соединений, порядок соединений и методы доступа к данным. Эти указания соответствуют указаниям, которые поддерживаются расширением pg_hint_plan. Для использования планов с наборами указаний необходимо включить расширение pg_hint_plan. При нахождении соответствующего замороженного запроса указания передаются pg_hint_plan для генерации выполняемого плана. Если расширение pg_hint_plan выключено, указания игнорируются и выполняется план, сформированный оптимизатором Postgres Pro. Планы с наборами указаний не зависят от идентификаторов объектов (OID) и остаются действительным при пересоздании таблиц, добавлении полей и других изменениях.template
: частный случай планаhintset
. Такие планы применяются только для запросов с именами таблиц, которые соответствуют регулярным выражениям, указанным в параметре конфигурации pgpro_multiplan.wildcards. Значениеpgpro_multiplan.wildcards
замораживается вместе с соответствующим запросом.
Базовые планы: наборы разрешённых планов, которые могут использоваться для выполнения запросов, если для них отсутствуют соответствующие замороженные планы. Как и замороженные планы типа
hintset
, базовые планы основаны на указаниях планировщика и требуют включения расширения pg_hint_plan. Если расширение pg_hint_plan выключено, указания игнорируются и выполняется план, сформированный оптимизатором Postgres Pro.
Используйте параметр конфигурации pgpro_multiplan.mode для указания списка включённых режимов и типов планов, разделённых запятой. По умолчанию для этого параметра указана пустая строка, и расширение pgpro_multiplan выключено.
G.3.4. Использование замороженных планов #
Чтобы разрешить использование замороженных планов, укажите значение frozen
в параметре pgpro_multiplan.mode.
Чтобы заморозить план для дальнейшего использования, выполните следующие шаги:
Зарегистрируйте запрос, план которого необходимо заморозить.
Измените план выполнения запроса.
Заморозьте план выполнения запроса.
G.3.4.1. Регистрация запроса #
Зарегистрировать запрос можно следующими способами:
С помощью функции pgpro_multiplan_register_query():
SELECT pgpro_multiplan_register_query(
query_string
,parameter_type
, ...);Здесь
query_string
— запрос с параметрами$
(аналогичноn
PREPARE
). Можно описать каждый тип параметра, используя необязательный аргумент функцииstatement_name
ASparameter_type
, или отказаться от явного определения типов параметров. В последнем случае Postgres Pro пытается определить тип каждого параметра из контекста. Эта функция возвращает уникальную паруsql_hash
иconst_hash
. После этого pgpro_multiplan будет отслеживать выполнение запросов, соответствующих сохранённому шаблону параметризованного запроса.-- Создайте таблицу 'a' CREATE TABLE a AS (SELECT * FROM generate_series(1,30) AS x); CREATE INDEX ON a(x); ANALYZE; -- Зарегистрируйте запрос SELECT sql_hash, const_hash FROM pgpro_multiplan_register_query('SELECT count(*) FROM a WHERE x = 1 OR (x > $2 AND x < $1) OR x = $1', 'int', 'int'); sql_hash | const_hash -----------------------+------------- -6037606140259443514 | 2413041345 (1 row)
С помощью параметра pgpro_multiplan.auto_tracking:
-- Установите для pgpro_multiplan.auto_tracking значение on SET pgpro_multiplan.auto_tracking = on; -- Выполните EXPLAIN для непараметризованного запроса EXPLAIN SELECT count(*) FROM a WHERE x = 1 OR (x > 11 AND x < 22) OR x = 22; Custom Scan (MultiplanScan) (cost=1.60..0.00 rows=1 width=8) Plan is: tracked SQL hash: 5393873830515778388 Const hash: 0 Plan hash: 0 -> Aggregate (cost=1.60..1.61 rows=1 width=8) -> Seq Scan on a (cost=0.00..1.60 rows=2 width=0) Filter: ((x = $1) OR ((x > $2) AND (x < $3)) OR (x = $4)) -- Выключите pgpro_multiplan.auto_tracking SET pgpro_multiplan.auto_tracking = off;
Все зарегистрированные запросы хранятся в локальном кеше, к которому можно обращаться с помощью представления pgpro_multiplan_local_cache.
G.3.4.2. Изменение плана выполнения запроса #
План выполнения запроса можно изменить при помощи переменных оптимизатора, указаний pg_hint_plan при включённом расширении или других расширений, например aqo. Информация о совместимости pgpro_multiplan с другими расширениями представлена в Подразделе G.3.7.
G.3.4.3. Заморозка плана выполнения запроса #
Для заморозки изменённого плана выполнения запроса используйте функцию pgpro_multiplan_freeze. Для необязательного параметра plan_type
можно задать значение serialized
, hintset
или template
. Значение по умолчанию — serialized
. Более подробно типы замороженных планов описаны в Подразделе G.3.3.
Все замороженные планы хранятся в представлении pgpro_multiplan_storage.
G.3.4.4. Пример замороженного плана #
Пример ниже показывает, как использовать замороженные планы.
-- План, который необходимо улучшить EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a WHERE x = 1 OR (x > 11 AND x < 22) OR x = 22; QUERY PLAN ------------------------------------------------------------------------- Aggregate (actual rows=1 loops=1) -> Seq Scan on a (actual rows=12 loops=1) Filter: ((x = 1) OR ((x > 11) AND (x < 22)) OR (x = 22)) Rows Removed by Filter: 18 Planning Time: 0.179 ms Execution Time: 0.069 ms (6 rows) -- Установите необходимый режим для pgpro_multiplan SET pgpro_multiplan.mode = 'frozen'; -- Зарегистрируйте запрос SELECT sql_hash, const_hash FROM pgpro_multiplan_register_query('SELECT count(*) FROM a WHERE x = 1 OR (x > $2 AND x < $1) OR x = $1', 'int', 'int'); sql_hash | const_hash ----------------------+------------ -6037606140259443514 | 2413041345 (1 row) -- Измените план выполнения запроса -- Запустите сканирование индекса, отключив последовательное сканирование SET enable_seqscan = 'off'; EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a WHERE x = 1 OR (x > 11 AND x < 22) OR x = 22; QUERY PLAN ---------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: tracked SQL hash: -6037606140259443514 Const hash: 2413041345 Plan hash: 0 -> Aggregate (actual rows=1 loops=1) -> Index Only Scan using a_x_idx on a (actual rows=12 loops=1) Filter: ((x = 1) OR ((x > $2) AND (x < $1)) OR (x = $1)) Rows Removed by Filter: 18 Heap Fetches: 30 Planning Time: 0.235 ms Execution Time: 0.099 ms (12 rows) -- Снова включите последовательное сканирование RESET enable_seqscan; -- Заморозьте план выполнения запроса SELECT pgpro_multiplan_freeze(); pgpro_multiplan_freeze ------------------------ t (1 row) -- Теперь замороженный план используется со сканированием индекса EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a WHERE x = 1 OR (x > 11 AND x < 22) OR x = 22; QUERY PLAN ---------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: frozen, serialized SQL hash: -6037606140259443514 Const hash: 2413041345 Plan hash: 0 -> Aggregate (actual rows=1 loops=1) -> Index Only Scan using a_x_idx on a (actual rows=12 loops=1) Filter: ((x = 1) OR ((x > $2) AND (x < $1)) OR (x = $1)) Rows Removed by Filter: 18 Heap Fetches: 30 Planning Time: 0.063 ms Execution Time: 0.119 ms (12 rows)
G.3.5. Использование базовых планов #
Если для определённого запроса нет замороженного плана, расширение pgpro_multiplan может использовать базовые планы, то есть набор разрешённых планов, созданных стандартным планировщиком или с помощью перепланирования запросов в реальном времени.
Чтобы разрешить использование разрешённых планов, укажите значение baseline
в параметре pgpro_multiplan.mode.
Чтобы автоматически добавлять планы, созданные с помощью перепланирования запросов в реальном времени, в список разрешённых планов, включите перепланирование и укажите значение auto_approve_plans
в параметре pgpro_multiplan.aqe_mode.
Чтобы добавить план, созданный стандартным планировщиком, в набор разрешённых планов, выполните следующие действия:
Для последующих запросов созданный план применяется без изменений, если он есть в наборе разрешённых планов. Если такого плана нет, то используется самый дешёвый план из набора разрешённых.
Примечание
Разрешённые планы могут использоваться только при работающем расширении pg_hint_plan. За подробной информацией обратитесь к разделу Совместимость с другими расширениями. Разрешённые планы не используются, если включён автоматический захват. Не забудьте отключить параметр pgpro_multiplan.auto_capturing после выполнения захвата.
G.3.5.1. Захват плана #
С помощью параметра pgpro_multiplan.auto_capturing можно включить захват всех выполняемых запросов. Получить доступ ко всем захваченным запросам можно с помощью представления pgpro_multiplan_captured_queries.
-- Создайте таблицу 'a' CREATE TABLE a AS SELECT x, x AS y FROM generate_series(1,1000) x; CREATE INDEX ON a(x); CREATE INDEX ON a(y); ANALYZE; -- Включите параметр auto_capturing SET pgpro_multiplan.mode = 'baseline' SET pgpro_multiplan.auto_capturing = 'on'; -- Выполните запрос SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 900; count ------- 100 (1 row) -- Выполните запрос ещё раз с другими константами, чтобы получить другой план SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 10 AND t2.y > 900; count ------- 0 (1 row) -- Теперь захваченные планы можно увидеть в соответствующем представлении SELECT * FROM pgpro_multiplan_captured_queries \gx dbid | 5 sql_hash | 6079808577596655075 plan_hash | -487722818968417375 queryid | -8984284243102644350 cost | 36.785 sample_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 900; query_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= $1 AND t2.y > $2; constants | 1000, 900 prep_const | hint_str | Leading(("t1" "t2" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") SeqScan("t1") explain_plan | Custom Scan (MultiplanScan) (cost=36.77..36.78 rows=1 width=8) + | Output: (count(*)) + | Plan is: tracked + | SQL hash: 6079808577596655075 + | Const hash: 0 + | Plan hash: -487722818968417375 + | Parameters: 0 + | -> Aggregate (cost=36.77..36.78 rows=1 width=8) + | Output: count(*) + | -> Hash Join (cost=11.28..36.52 rows=100 width=0) + | Hash Cond: (t1.x = t2.x) + | -> Seq Scan on public.a t1 (cost=0.00..20.50 rows=1000 width=4) + | Output: t1.x, t1.y + | Filter: (t1.y <= 1000) + | -> Hash (cost=10.03..10.03 rows=100 width=4) + | Output: t2.x + | Buckets: 1024 Batches: 1 Memory Usage: 12kB + | -> Index Scan using a_y_idx on public.a t2 (cost=0.28..10.03 rows=100 width=4)+ | Output: t2.x + | Index Cond: (t2.y > 900) + | Query Identifier: -8984284243102644350 + | -[ RECORD 2 ]-+----------------------------------------------------------------------------------------------------- dbid | 5 sql_hash | 6079808577596655075 plan_hash | 2719320099967191582 queryid | -8984284243102644350 cost | 18.997500000000002 sample_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 10 AND t2.y > 900; query_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= $1 AND t2.y > $2; constants | 10, 900 prep_const | hint_str | Leading(("t2" "t1" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") IndexScan("t1" "a_y_idx") explain_plan | Custom Scan (MultiplanScan) (cost=18.99..19.00 rows=1 width=8) + | Output: (count(*)) + | Plan is: tracked + | SQL hash: 6079808577596655075 + | Const hash: 0 + | Plan hash: 2719320099967191582 + | Parameters: 0 + | -> Aggregate (cost=18.99..19.00 rows=1 width=8) + | Output: count(*) + | -> Hash Join (cost=8.85..18.98 rows=1 width=0) + | Hash Cond: (t2.x = t1.x) + | -> Index Scan using a_y_idx on public.a t2 (cost=0.28..10.03 rows=100 width=4) + | Output: t2.x, t2.y + | Index Cond: (t2.y > 900) + | -> Hash (cost=8.45..8.45 rows=10 width=4) + | Output: t1.x + | Buckets: 1024 Batches: 1 Memory Usage: 9kB + | -> Index Scan using a_y_idx on public.a t1 (cost=0.28..8.45 rows=10 width=4) + | Output: t1.x + | Index Cond: (t1.y <= 10) + | Query Identifier: -8984284243102644350 + | -- Отключите автоматический захват. Это не повлияет на планы, которые были захвачены ранее. SET pgpro_multiplan.auto_capturing = 'off';
G.3.5.2. Одобрение плана #
Чтобы одобрить любой план из представления pgpro_multiplan_captured_queries
, используйте функцию pgpro_multiplan_captured_approve() с параметрами dbid
, sql_hash
и plan_hash
.
-- Вручную одобрите план со сканированием по индексам SELECT pgpro_multiplan_captured_approve(5, 6079808577596655075, 2719320099967191582); pgpro_multiplan_captured_approve ---------------------------------- t (1 row) -- Или одобрите планы, выбранные из списка захваченных планов SELECT pgpro_multiplan_captured_approve(dbid, sql_hash, plan_hash) FROM pgpro_multiplan_captured_queries WHERE query_string like '%SELECT % FROM a t1, a t2%'; pgpro_multiplan_captured_approve ---------------------------------- t (1 row) -- Одобренные планы автоматически удаляются из хранилища захваченных планов SELECT count(*) FROM pgpro_multiplan_captured_queries; count ------- 0 (1 row) -- Одобренные планы можно увидеть в представлении pgpro_multiplan_storage SELECT * FROM pgpro_multiplan_storage \gx -[ RECORD 1 ]-+------------------------------------------------------------------------------------------------ dbid | 5 sql_hash | 6079808577596655075 const_hash | 0 plan_hash | -487722818968417375 valid | t cost | 36.785 sample_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 900; query_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= $1 AND t2.y > $2; paramtypes | query | <> plan | <> plan_type | baseline hintstr | Leading(("t1" "t2" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") SeqScan("t1") wildcards | -[ RECORD 2 ]-+------------------------------------------------------------------------------------------------ dbid | 5 sql_hash | 6079808577596655075 const_hash | 0 plan_hash | 2719320099967191582 valid | t cost | 18.997500000000002 sample_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 10 AND t2.y > 900; query_string | SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= $1 AND t2.y > $2; paramtypes | query | <> plan | <> plan_type | baseline hintstr | Leading(("t2" "t1" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") IndexScan("t1" "a_y_idx") wildcards |
G.3.5.3. Пример разрешённого плана #
Ниже показан пример использования разрешённых планов.
-- Включите параметр auto_capturing SET pgpro_multiplan.mode = 'baseline' SET pgpro_multiplan.auto_capturing = 'on'; -- Выполните запрос EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 900; QUERY PLAN -------------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: tracked SQL hash: 6079808577596655075 Const hash: 0 Plan hash: -487722818968417375 -> Aggregate (actual rows=1 loops=1) -> Hash Join (actual rows=100 loops=1) Hash Cond: (t1.x = t2.x) -> Seq Scan on a t1 (actual rows=1000 loops=1) Filter: (y <= 1000) -> Hash (actual rows=100 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Index Scan using a_y_idx on a t2 (actual rows=100 loops=1) Index Cond: (y > 900) Planning Time: 0.543 ms Execution Time: 0.688 ms (16 rows) -- Затем выполните запрос снова с другими константами EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 10 AND t2.y > 900; QUERY PLAN -------------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: tracked SQL hash: 6079808577596655075 Const hash: 0 Plan hash: 2719320099967191582 -> Aggregate (actual rows=1 loops=1) -> Hash Join (actual rows=0 loops=1) Hash Cond: (t2.x = t1.x) -> Index Scan using a_y_idx on a t2 (actual rows=100 loops=1) Index Cond: (y > 900) -> Hash (actual rows=10 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Index Scan using a_y_idx on a t1 (actual rows=10 loops=1) Index Cond: (y <= 10) Planning Time: 0.495 ms Execution Time: 0.252 ms (16 rows) -- Отключите автоматический захват SET pgpro_multiplan.auto_capturing = 'off'; -- Одобрите все захваченные планы SELECT pgpro_multiplan_captured_approve(dbid, sql_hash, plan_hash) FROM pgpro_multiplan_captured_queries; pgpro_multiplan_captured_approve ---------------------------------- t t (2 rows) -- План не меняется, поскольку он входит в число разрешённых EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 900; QUERY PLAN -------------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: baseline SQL hash: 6079808577596655075 Const hash: 0 Plan hash: -487722818968417375 -> Aggregate (actual rows=1 loops=1) -> Hash Join (actual rows=100 loops=1) Hash Cond: (t1.x = t2.x) -> Seq Scan on a t1 (actual rows=1000 loops=1) Filter: (y <= 1000) -> Hash (actual rows=100 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Index Scan using a_y_idx on a t2 (actual rows=100 loops=1) Index Cond: (y > 900) Planning Time: 0.426 ms Execution Time: 0.519 ms (16 rows) -- В обычной ситуации в этом плане выполнялось бы последовательное сканирование для обеих таблиц, но сейчас применяется самый дешёвый из набора разрешённых EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF) SELECT count(*) FROM a t1, a t2 WHERE t1.x = t2.x AND t1.y <= 1000 AND t2.y > 0; QUERY PLAN -------------------------------------------------------------------------------- Custom Scan (MultiplanScan) (actual rows=1 loops=1) Plan is: baseline SQL hash: 6079808577596655075 Const hash: 0 Plan hash: 2719320099967191582 -> Aggregate (actual rows=1 loops=1) -> Hash Join (actual rows=1000 loops=1) Hash Cond: (t2.x = t1.x) -> Index Scan using a_y_idx on a t2 (actual rows=1000 loops=1) Index Cond: (y > $2) -> Hash (actual rows=1000 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 44kB -> Index Scan using a_y_idx on a t1 (actual rows=1000 loops=1) Index Cond: (y <= $1) Planning Time: 2.473 ms Execution Time: 1.859 ms (16 rows)
G.3.6. Резервные копии замороженных планов #
Расширение pgpro_multiplan позволяет создавать резервные копии замороженных планов и затем восстанавливать эти планы в текущую базу данных. Это может быть полезно для переноса планов между базами данных или экземплярами серверов.
Чтобы создать копию замороженных планов, используйте представление pgpro_multiplan_storage следующим образом:
CREATE TABLE storage_copy AS SELECT s.* FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'db_name';
Чтобы восстановить замороженные планы из резервной копии, вызовите функцию pgpro_multiplan_restore():
SELECT s.query_string, res.sql_hash IS NOT NULL AS success FROM storage_copy s, LATERAL pgpro_multiplan_restore(s.query_string, s.hintstr, s.paramtypes, s.plan_type) res;
Примечание
Планы могут быть восстановлены только при работающем расширении pg_hint_plan, см. раздел Совместимость с другими расширениями.
Планы всегда восстанавливаются в текущую базу данных. Чтобы восстановить планы в другую базу данных, сначала подключитесь к ней. Таким образом, рекомендуется создавать копии планов только из одной необходимой базы данных, как для db_name
в примерах в этой секции. Если вам нужно перенести планы для нескольких баз данных, создайте для них отдельные копии, подключитесь последовательно к каждой целевой базе данных и восстановите планы из соответствующих копий.
G.3.6.1. Ограничения #
При создании копий замороженных планов и их восстановлении обратите внимание на следующие ограничения:
Можно восстановить только замороженные планы.
Нельзя восстановить замороженные планы, имеющие тип
template
. Поддерживаются только планы типовserialized
иhintset
.Если вы создаёте копию планов из нескольких баз данных, и эти базы данных содержат разные замороженные планы для одинаковых запросов, только первый конфликтующий план будет восстановлен.
Можно восстановить только планы для допустимых запросов, что означает, что все отношения, используемые в запросе, должны существовать в текущей базе данных.
G.3.6.2. Сценарии использования #
Этот раздел описывает как создать копии замороженных планов и восстановить их в разных популярных сценариях.
G.3.6.2.1. Обновление версии сервера #
Выполните шаги ниже, чтобы сохранить замороженные планы при обновлении сервера со старой версии с несовместимым хранилищем данных.
Создайте копию замороженных планов до обновления.
CREATE TABLE storage_copy AS SELECT s.* FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'db_name';
Обновите версию сервера.
Восстановите замороженные планы.
SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type) FROM storage_copy;
G.3.6.2.2. Перенос планов между экземплярами серверов #
Чтобы перенести замороженные планы между двумя серверами, выполните следующее:
Подключитесь к исходному серверу.
Создайте копию замороженных планов в таблицу.
CREATE TABLE storage_copy AS SELECT s.* FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'db_name';
Используйте утилиту pg_dump, чтобы выгрузить таблицу в файл.
$ pg_dump --table storage_copy -Ft postgres > storage_copy.tar
Подключитесь к целевому серверу и нужной базе данных.
Переместите созданный файл выгрузки в целевую файловую систему.
Используйте утилиту pg_restore, чтобы восстановить таблицу с замороженными планами из файла выгрузки.
$ pg_restore --dbname postgres -Ft storage_copy.tar
Восстановите замороженные планы.
SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type) FROM storage_copy; DROP TABLE storage_copy;
G.3.6.2.3. Перенос планов из "песочницы" в обычное хранилище #
Чтобы перенести замороженные планы из "песочницы" в обычное хранилище, выполните следующие шаги:
Установите параметру pgpro_multiplan.sandbox значение
on
и создайте копию замороженных планов из "песочницы".SET pgpro_multiplan.sandbox = ON; CREATE TABLE storage_copy AS SELECT s.* FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'db_name';
Установите для параметра
pgpro_multiplan.sandbox
значениеoff
и восстановите замороженные планы в обычное хранилище.SET pgpro_multiplan.sandbox = OFF; SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type) FROM storage_copy;
G.3.6.2.4. Перенос планов между базами данных #
Чтобы перенести замороженные планы из одной базы данных в другую, подключитесь к целевой базе данных и восстановите планы, как показано ниже.
SELECT pgpro_multiplan_restore(s.query_string, s.hintstr, s.paramtypes, s.plan_type) FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'db_name';
Здесь db_name
— это имя базы данных, из которой вы хотите перенести планы.
G.3.6.2.5. Пример переноса планов #
Этот пример показывает, как перенести планы с одного экземпляра сервера на другой.
-- Подключитесь к исходному серверу psql (17.4) Type "help" for help. -- В этом примере 1000 планов хранится в представлении pgpro_multiplan_storage postgres=# select count(*) from pgpro_multiplan_storage; count ------- 1000 (1 row) -- Скопируйте замороженные планы из базы данных postgres в таблицу postgres=# CREATE TABLE storage_copy AS SELECT s.* FROM pgpro_multiplan_storage s JOIN pg_database d ON s.dbid = d.oid WHERE d.datname = 'postgres'; -- Выгрузите таблицу в файл архива $ pg_dump --table storage_copy -Ft postgres > storage_copy.tar -- Отключитесь от исходного сервера -- Подключитесь к целевому серверу ./psql postgres psql (16.8) Type "help" for help. -- Создайте расширение pgpro_multiplan и включите его postgres=# create extension pgpro_multiplan; CREATE EXTENSION SET pgpro_multiplan.mode = 'frozen'; SET -- Этот сервер не содержит замороженных планов postgres=# select count(*) from pgpro_multiplan_storage; count ------- 0 (1 row) -- Переместите файл выгрузки с замороженными планами в целевую файловую систему -- Восстановите таблицу с замороженными планами из файла выгрузки $ pg_restore --dbname postgres -Ft storage_copy.tar -- Восстановите замороженные планы из таблицы с помощью функции pgpro_multiplan_restore postgres=# SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type) FROM storage_copy; pgpro_multiplan_restore ---------------------------------- (8436876698844323073,871432885) (8436876698844323073,573678316) (8436876698844323073,1999378082) (8436876698844323073,1681603536) (8436876698844323073,3959620774) ... (8436876698844323073,1263226437) (8436876698844323073,4053700861) (8436876698844323073,2418458596) (8436876698844323073,413896030) (1000 rows) -- Функция восстановила 1000 замороженных планов. Результат показан в виде пар sql_hash и const_hash -- Замороженные запросы были однотипными и отличались только константами, поэтому sql_hash одинаковый для всех планов -- Удалите таблицу, используемую для восстановления планов postgres=# DROP TABLE storage_copy; DROP TABLE -- Целевой сервер теперь тоже хранит 1000 замороженных планов postgres=# select count(*) from pgpro_multiplan_storage; count ------- 1000 (1 row) -- Выключите pgpro_multiplan и выполните запрос SET pgpro_multiplan.mode = ''; SET postgres=# EXPLAIN (COSTS OFF) SELECT * FROM a WHERE x > 10; QUERY PLAN -------------------- Seq Scan on a Filter: (x > 10) (2 rows) -- Включите pgpro_multiplan и выполните тот же запрос ещё раз -- Теперь используется один из восстановленных планов SET pgpro_multiplan.mode = 'frozen'; SET postgres=# EXPLAIN (COSTS OFF) SELECT * FROM a WHERE x > 10; QUERY PLAN ------------------------------------- Custom Scan (MultiplanScan) Plan is: frozen, serialized SQL hash: 8436876698844323073 Const hash: 2295408638 Plan hash: 0 -> Index Scan using a_x_idx on a Index Cond: (x > 10) (7 rows)
G.3.7. Совместимость с другими расширениями #
Для обеспечения совместимости pgpro_multiplan с другими расширениями необходимо в файле postgresql.conf
в переменной shared_preload_libraries
указать имена библиотек в определённом порядке:
pg_hint_plan: расширение pgpro_multiplan необходимо загрузить после pg_hint_plan.
shared_preload_libraries = 'pg_hint_plan, pgpro_multiplan'
aqo: расширение pgpro_multiplan необходимо загружать до aqo.
shared_preload_libraries = 'pgpro_multiplan, aqo'
pgpro_stats: расширение pgpro_multiplan необходимо загружать после pgpro_stats.
shared_preload_libraries = 'pgpro_stats, pgpro_multiplan'
G.3.8. Идентификация запросов #
Запрос в текущей базе данных идентифицируется уникальной парой sql_hash
и const_hash
.
sql_hash
— это хеш, сформированный на основе дерева разбора без учёта параметров и констант. Псевдонимы полей и таблиц не игнорируются, поэтому один и тот же запрос с разными псевдонимами будет иметь разные значения sql_hash
.
const_hash
— хеш, сгенерированный на основе всех присутствующих в запросе констант. Константы с одинаковым значением, но разным типом, например 1
и '1'
, выдадут разное значение хеша.
G.3.9. Автоматическое приведение типов #
pgpro_multiplan пытается автоматически приводить типы констант из запроса к типам параметров запроса, для которого план был заморожен или добавлен в список разрешённых. Если привести типы невозможно, план игнорируется.
SELECT sql_hash, const_hash FROM pgpro_multiplan_register_query('SELECT count(*) FROM a WHERE x = $1', 'int'); -- Приведение типов возможно EXPLAIN SELECT count(*) FROM a WHERE x = '1'; QUERY PLAN ------------------------------------------------------------- Custom Scan (MultiplanScan) (cost=1.38..1.39 rows=1 width=8) Plan is: tracked SQL hash: -5166001356546372387 Const hash: 0 Plan hash: 0 -> Aggregate (cost=1.38..1.39 rows=1 width=8) -> Seq Scan on a (cost=0.00..1.38 rows=1 width=0) Filter: (x = $1) -- Приведение типов возможно EXPLAIN SELECT count(*) FROM a WHERE x = 1::bigint; QUERY PLAN ------------------------------------------------------------- Custom Scan (MultiplanScan) (cost=1.38..1.39 rows=1 width=8) Plan is: tracked SQL hash: -5166001356546372387 Const hash: 0 Plan hash: 0 -> Aggregate (cost=1.38..1.39 rows=1 width=8) -> Seq Scan on a (cost=0.00..1.38 rows=1 width=0) Filter: (x = $1) -- Приведение типов невозможно EXPLAIN SELECT count(*) FROM a WHERE x = 1111111111111; QUERY PLAN ------------------------------------------------------- Aggregate (cost=1.38..1.39 rows=1 width=8) -> Seq Scan on a (cost=0.00..1.38 rows=1 width=0) Filter: (x = '1111111111111'::bigint)
G.3.10. Интеграция с перепланированием запросов в реальном времени #
Расширение pgpro_multiplan может работать совместно с перепланированием запросов в реальном времени, предоставляя более гибкие возможности для управления планами выполнения запросов.
Перепланирование запросов в реальном времени пытается переоптимизировать запрос, если во время выполнения запроса срабатывает определённый триггер, указывающий на неоптимальность плана. Чтобы включить перепланирование запросов в реальном времени, используйте параметр конфигурации replan_enable.
Чтобы включить функциональность, связанную с перепланированием запросов в реальном времени, используйте параметр конфигурации pgpro_multiplan.aqe_mode.
G.3.11. Статистика #
Чтобы собирать статистику об использовании замороженных и разрешённых планов, укажите значение statistics
в параметре pgpro_multiplan.mode. Эта статистика хранится в представлении pgpro_multiplan_stats. Параметр pgpro_multiplan.max_stats задаёт максимальное количество собираемых статистических значений. При достижении этого ограничения дальнейшая статистика будет игнорироваться. Если план изменяется, статистика использования этого плана сбрасывается и пересчитывается с новым plan_hash
.
Для получения более детальной статистики планирования и выполнения запросов можно использовать расширение pgpro_stats (см. секцию Совместимость с другими расширениями). Доступ к этой статистике можно получить с помощью представления pgpro_stats_statements.
Вы можете объединить информацию из представлений pgpro_multiplan_stats
и pgpro_stats_statements
по полю planid
.
Следующий пример демонстрирует, как собирать и просматривать статистику. В нём используется запрос и замороженный план из примера замороженного плана.
-- Включите сбор статистики SET pgpro_multiplan.mode = 'frozen, statistics'; -- Выполните запрос SELECT count(*) FROM a WHERE x = 1 OR (x > 11 AND x < 22) OR x = 22; count ------- 12 (1 row) -- Теперь можно посмотреть статистику использования плана SELECT * FROM pgpro_multiplan_stats; dbid | sql_hash | const_hash | plan_hash | planid | counter ------+---------------------+------------+-----------+---------------------+--------- 5 | 6062491547151210914 | 2413041345 | 0 | 3549961214127427294 | 1 (1 row)
G.3.12. Представления #
G.3.12.1. Представление pgpro_multiplan_storage
#
Представление pgpro_multiplan_storage
содержит подробную информацию обо всех замороженных и разрешённых планах. Столбцы представления показаны в Таблице G.2.
Таблица G.2. Столбцы pgpro_multiplan_storage
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
const_hash | bigint | Хеш непараметризованных констант |
plan_hash | bigint | Внутренний идентификатор разрешённого плана, 0 — для замороженных планов |
valid | boolean | FALSE , если план был аннулирован при последнем использовании |
cost | float | Стоимость разрешённого плана, 0 — для замороженных планов |
sample_string | text | Непараметризованный запрос с константами, для которого план был заморожен или добавлен в список разрешённых |
query_string | text | Параметризованный запрос, для которого план был заморожен или добавлен в список разрешённых |
paramtypes | regtype[] | Массив с типами параметров, использованными в запросе |
query | text | Внутреннее представление запроса |
plan | text | Внутреннее представление плана |
plan_type | text | Тип плана. Для замороженных планов: serialized , hintset или template . Для разрешённых планов: baseline |
hintstr | text | Набор указаний, сформированный на основе плана |
wildcards | text | Шаблоны, используемые для замороженного плана template , NULL для остальных типов планов |
G.3.12.2. Представление pgpro_multiplan_local_cache
#
Представление pgpro_multiplan_local_cache
содержит подробную информацию о зарегистрированных и замороженных операторах в локальном кеше. Столбцы представления показаны в Таблице G.3.
Таблица G.3. Столбцы pgpro_multiplan_local_cache
Имя | Тип | Описание |
---|---|---|
sql_hash | bigint | Внутренний идентификатор запроса |
const_hash | bigint | Хеш непараметризованных констант |
fs_is_frozen | boolean | TRUE , если оператор был заморожен |
fs_is_valid | boolean | TRUE , если оператор действителен |
ps_is_valid | boolean | TRUE , если оператор должен быть перепроверен |
query_string | text | Запрос, зарегистрированный функцией pgpro_multiplan_register_query |
query | text | Внутреннее представление запроса |
paramtypes | regtype[] | Массив с типами параметров, использованными в запросе |
hintstr | text | Набор указаний, сформированный на основе замороженного плана |
G.3.12.3. Представление pgpro_multiplan_captured_queries
#
Представление pgpro_multiplan_captured_queries
содержит подробную информацию обо всех запросах, отслеживаемых в сеансах. Столбцы представления показаны в Таблице G.4.
Таблица G.4. Столбцы pgpro_multiplan_captured_queries
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
queryid | bigint | Стандартный идентификатор запроса |
plan_hash | bigint | Внутренний идентификатор плана |
planid | bigint | Идентификатор плана, совместимый с расширением pgpro_stats |
cost | float | Стоимость плана |
sample_string | text | Непараметризованный запрос с константами |
query_string | text | Параметризованный запрос |
constants | text | Набор констант в запросе |
prep_consts | text | Набор констант, использованных для выполнения (EXECUTE ) подготовленного оператора |
hintstr | text | Набор указаний, сформированный на основе плана |
explain_plan | text | План, показанный командой EXPLAIN |
G.3.12.4. Представление pgpro_multiplan_stats
#
Представление pgpro_multiplan_stats
предоставляет статистику использования замороженных и разрешённых планов. Столбцы представления показаны в Таблице G.5.
Таблица G.5. Столбцы pgpro_multiplan_stats
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
plan_hash | bigint | Внутренний идентификатор плана |
planid | bigint | Идентификатор плана, совместимый с расширением pgpro_stats |
counter | bigint | Количество использований плана |
G.3.12.5. Представление aqe_triggers
#
Представление aqe_triggers
содержит информацию об индивидуальных значениях триггеров перепланирования. Столбцы представления показаны в Таблице G.6.
Таблица G.6. Столбцы aqe_triggers
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
query_string | text | Параметризованный запрос |
execution_time | int | Значение для триггера времени выполнения запроса, в миллисекундах. NULL , если используется глобальное значение триггера |
memory | int | Значение для триггера потребления памяти рабочим процессом. NULL , если используется глобальное значение триггера |
underestimation_rate | double | Коэффициент для триггера количества обработанных кортежей узлов. NULL , если используется глобальное значение триггера |
G.3.12.6. Представление aqe_stats
#
Представление aqe_stats
содержит сводную статистику о переоптимизациях с помощью перепланирования запросов в реальном времени. Это представление содержит одну строку для каждой комбинации идентификатора базы данных, запроса и плана выполнения. Столбцы представления показаны в Таблице G.7.
Таблица G.7. Столбцы aqe_stats
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
planid | bigint | Идентификатор плана выполнения запроса |
query | text | Внутреннее представление запроса |
last_updated | timestamp with time zone | Время последнего обновления статистики |
exec_num | bigint | Количество выполнений запроса |
min_attempts | integer | Минимальное количество переоптимизаций запроса |
max_attempts | integer | Максимальное количество переоптимизаций запроса |
total_attempts | integer | Общее количество переоптимизаций запроса |
reason_repeated_plan | bigint | Количество отключений перепланирования запросов в реальном времени из-за генерации повторного плана выполнения |
reason_no_data | bigint | Количество отключений перепланирования запросов в реальном времени из-за отсутствия новой информации, полученной во время выполнения |
reason_max_reruns | bigint | Количество отключений перепланирования запросов в реальном времени из-за достижения максимального количества перезапусков |
reason_external | bigint | Количество раз, когда перепланирование запросов в реальном времени было отключено расширением, например, pgpro_multiplan |
reruns_forced | bigint | Общее количество переоптимизаций, вызванных ручным триггером |
reruns_time | bigint | Общее количество переоптимизаций, вызванных триггером времени выполнения запроса |
reruns_underestimation | bigint | Общее количество переоптимизаций, вызванных триггером количества обработанных кортежей узлов |
reruns_memory | bigint | Общее количество переоптимизаций, вызванных триггером потребления памяти рабочим процессом |
min_planning_time | double precision | Минимальное время, затраченное на планирование, в миллисекундах |
max_planning_time | double precision | Максимальное время, затраченное на планирование, в миллисекундах |
mean_planning_time | double precision | Среднее время, затраченное на планирование, в миллисекундах |
stddev_planning_time | double precision | Стандартное отклонение времени, затраченного на планирование, в миллисекундах |
min_exec_time | double precision | Минимальное время, затраченное на выполнение запроса, в миллисекундах |
max_exec_time | double precision | Максимальное время, затраченное на выполнение запроса, в миллисекундах |
mean_exec_time | double precision | Среднее время, затраченное на выполнение запроса, в миллисекундах |
stddev_exec_time | double precision | Стандартное отклонение времени, затраченного на выполнение запроса, в миллисекундах |
G.3.13. Функции #
Вызывать нижеуказанные функции могут только суперпользователи.
-
pgpro_multiplan_register_query(
query_string
text
) returns record
pgpro_multiplan_register_query(
#query_string
text
,VARIADIC
regtype[]
) returns record Сохраняет запрос, описанный в параметре
query_string
, в локальном кеше, к которому можно получить доступ с помощью представления pgpro_multiplan_local_cache. Возвращает уникальную паруsql_hash
иconst_hash
.-
pgpro_multiplan_unregister_query() returns bool
# Удаляет запрос, который был зарегистрирован, но не был заморожен, из представления
pgpro_multiplan_local_cache
. Если нет ошибок, возвращаетtrue
.-
pgpro_multiplan_freeze(
#plan_type
text
) returns bool Замораживает последний использованный план для оператора и сохраняет его в представлении pgpro_multiplan_storage. Допустимые значения необязательного аргумента
plan_type
:serialized
,hintset
иtemplate
. Значениеserialized
означает, что используется план запроса, основанный на сериализованном представлении. При использовании значенияhintset
pgpro_multiplan использует план запроса на основе набора указаний, который формируется на этапе выполнения зарегистрированного запроса. При использовании значенияtemplate
pgpro_multiplan создаёт план с шаблонами, который может применяться к запросам с именами таблиц, совпадающими с регулярными выражениями, указанными в параметре конфигурации pgpro_multiplan.wildcards. Содержимоеpgpro_multiplan.wildcards
замораживается вместе с запросом для плановtemplate
. Если аргументplan_type
опущен, по умолчанию используется план типаserialized
. Если нет ошибок, возвращаетtrue
.-
pgpro_multiplan_unfreeze(
#sql_hash
bigint
,const_hash
bigint
) returns bool Удаляет план только из представления
pgpro_multiplan_storage
, но оставляет запрос в представленииpgpro_multiplan_local_cache
. Если нет ошибок, возвращаетtrue
.-
pgpro_multiplan_remove(
#sql_hash
bigint
,const_hash
bigint
) returns bool Удаляет замороженный оператор с указанными параметрами
sql_hash
иconst_hash
. Работает как функцииpgpro_multiplan_unfreeze
иpgpro_multiplan_unregister_query
, вызываемые последовательно. Если нет ошибок, возвращаетtrue
.-
pgpro_multiplan_reset(
#dbid
oid
) returns bigint Удаляет все записи в представлении
pgpro_multiplan_storage
для указанной базы данных. Чтобы удалить данные, собранные pgpro_multiplan для текущей базы данных, не указывайтеdbid
. Чтобы сбросить данные для всех баз данных, установите для параметраdbid
значение NULL. Возвращает количество удалённых записей.-
pgpro_multiplan_reload_frozen_plancache() returns bool
# Удаляет все замороженные планы и снова загружает их в представление
pgpro_multiplan_storage
. Также удаляет операторы, которые были зарегистрированы, но не заморожены. Если нет ошибок, возвращаетtrue
.-
pgpro_multiplan_stats() returns table
# Возвращает статистику использования планов из представления pgpro_multiplan_stats.
-
pgpro_multiplan_registered_query(
#sql_hash
bigint
,const_hash
bigint
) returns table Возвращает зарегистрированный запрос с указанными параметрами
sql_hash
иconst_hash
, даже если он не заморожен, только для целей отладки. Работает, если запрос зарегистрирован в текущем обслуживающем процессе или заморожен в текущей базе данных.-
pgpro_multiplan_captured_approve(
#dbid
oid
,sql_hash
bigint
,plan_hash
bigint
) returns bool Добавляет указанный план для захваченного запроса в набор базовых (разрешённых) планов и сохраняет его в представлении
pgpro_multiplan_storage
. Если план был успешно добавлен, возвращаетtrue
.-
pgpro_multiplan_remove_baseline(
#dbid
oid
,sql_hash
bigint
,plan_hash
bigint
) returns bool Удаляет указанный план из набора базовых (разрешённых) планов и представления
pgpro_multiplan_storage
. Если план был успешно удалён, возвращаетtrue
.-
pgpro_multiplan_set_plan_type(
#sql_hash
bigint
,const_hash
bigint
,plan_type
text
) returns bool Устанавливает тип плана запроса для замороженного оператора. Допустимые значения аргумента
plan_type
:serialized
,hintset
иtemplate
. Чтобы иметь возможность использовать план запроса типаhintset
илиtemplate
, необходимо загрузить модуль pg_hint_plan. Если тип плана был успешно изменён, возвращаетtrue
.-
pgpro_multiplan_hintset_update(
#sql_hash
bigint
,const_hash
bigint
,hintset
text
) returns bool Заменяет сгенерированный набор указаний пользовательским набором указаний. Строка с такими пользовательскими указаниями не должна задаваться в виде особого комментария, как в pg_hint_plan, то есть она не должна начинаться с
/*+
и заканчиваться*/
. Если план с указаниями был успешно изменён, возвращаетсяtrue
.-
pgpro_multiplan_captured_clean() returns bigint
# Удаляет все записи из представления pgpro_multiplan_captured_queries. Возвращает количество удалённых записей.
-
get_sql_hash(
#query_string
text
) returns bigint Возвращает внутренний идентификатор (
sql_hash
) для указанного запроса.-
set_aqe_trigger(
trigger_name
text
,trigger_val
int
,query_string
text
) returns bool
set_aqe_trigger(
#trigger_name
text
,trigger_val
double precision
,query_string
text
) returns bool Задаёт или сбрасывает индивидуальное значение триггера перепланирования запросов в реальном времени для указанного запроса. Индивидуальное значение триггера переопределяет глобальное значение триггера, указанное в параметре конфигурации. Чтобы эта функциональность работала, значение
individual_triggers
должно быть указано в параметре pgpro_multiplan.aqe_mode.Эта функция имеет следующие аргументы:
trigger_name
: имя триггера. Разрешены следующие значения:execution_time
: триггер времени выполнения запроса. Соответствует параметру конфигурации replan_query_execution_time.memory
: триггер потребления памяти рабочим процессом. Соответствует параметру конфигурации replan_memory_limit.underestimation_rate
: триггер количества обработанных кортежей узлов. Соответствует параметру конфигурации replan_overrun_limit.
trigger_val
: значение триггера. Для триггеровexecution_time
иmemory
указывайте целочисленные значения. Дляunderestimation_rate
можно указать значения с двойной точностью. Чтобы сбросить индивидуальное значение триггера, передайте в качестве значенияNULL
или отрицательное число меньше -1.query_string
: текст запроса.
Если нет ошибок, эта функция возвращает
true
.-
aqe_triggers_reset(
#dbid
oid
) returns bigint Удаляет все записи из представления
aqe_triggers
для указанной базы данных. Чтобы очистить представлениеaqe_triggers
для текущей базы данных, не указывайтеdbid
. Чтобы удалить записи из представления для всех баз данных, установите для параметраdbid
значениеNULL
. Возвращает количество удалённых записей.-
aqe_stats_reset(
#dbid
oid
) returns bigint Удаляет все записи из представления
aqe_stats
для указанной базы данных. Чтобы очистить представлениеaqe_stats
для текущей базы данных, не указывайтеdbid
. Чтобы удалить записи из представления для всех баз данных, установите для параметраdbid
значениеNULL
. Возвращает количество удалённых записей.-
pgpro_multiplan_restore(
#query_string
text
,hintstr
text
text,paramtypes
regtype[]
,plan_type
text
) returns record Восстанавливает замороженный план для указанного запроса в текущую базу данных.
Эта функция имеет следующие аргументы:
query_string
: Запрос с параметрами$
(аналогичноn
PREPARE
), для которого восстанавливается замороженный план на основе набора указаний.statement_name
AShintstr
: Набор указаний, поддерживаемых расширением pg_hint_plan. Если для аргумента указано значениеNULL
или пустая строка, будет использоваться стандартный план.parameter_type
: Массив с типами параметров, используемых в запросе. Если для аргумента указано значениеNULL
, типы параметров должны быть определены автоматически.plan_type
: Тип плана. Допустимые значения:serialized
иhintset
. План с типомtemplate
не поддерживается.
Функция возвращает уникальную пару
sql_hash
иconst_hash
, если план был успешно восстановлен. В противном случае, она возвращаетNULL
.
G.3.14. Параметры конфигурации #
pgpro_multiplan.mode
(string
) #Список включённых режимов pgpro_multiplan, разделённых запятой. Доступны следующие значения:
frozen
: разрешает использование замороженных планов с типамиserialized
иhintset
.wildcards
: разрешает использование замороженных планов с типомtemplate
.baseline
: разрешает использование базовых (разрешённых) планов.statistics
: разрешает сбор статистики использования планов. Эта статистика хранится в представлении pgpro_multiplan_stats. Это значение параметра может быть указано только совместно с одним или несколькими типами планов.
SET pgpro_multiplan.mode = 'frozen, wildcards, baseline, statistics';
Подробнее о типах планов можно узнать в разделе Поддерживаемые режимы и типы планов. За информацией о сборе статистики обратитесь к разделу Статистика.
По умолчанию для параметра
pgpro_multiplan.mode
задана пустая строка, что означает выключение pgpro_multiplan. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.aqe_mode
(string
) #Список включённых возможностей, связанных с перепланированием запросов в реальном времени, разделённых запятой. Доступны следующие значения:
auto_approve_plans
: позволяет pgpro_multiplan автоматически добавлять планы, созданные с помощью перепланирования запросов в реальном времени, в список разрешённых планов.individual_triggers
: разрешает переопределять и настраивать значения триггеров перепланирования запросов в реальном времени для отдельных запросов с помощью функции set_aqe_trigger(). Все индивидуальные значения триггеров отображаются в представлении aqe_triggers.statistics
: позволяет pgpro_multiplan собирать статистику для всех операторов, которые рассматриваются для переоптимизации с помощью перепланирования запросов в реальном времени. Эта статистика хранится в разделяемой памяти до выключения сервера и доступна с помощью представления aqe_stats. Статистика не реплицируется. Для работы этой функциональности необходимо включить вычисление идентификатора запроса с помощью параметра конфигурации compute_query_id. Параметр pgpro_multiplan.aqe_max_stats задаёт максимальное количество собираемых статистических значений — дальнейшая статистика будет игнорироваться.
SET pgpro_multiplan.aqe_mode = 'auto_approve_plans, individual_triggers, statistics';
Чтобы эта функциональность работала, перепланирование запросов в реальном времени должно быть включено с помощью параметра конфигурации replan_enable.
По умолчанию для параметра
pgpro_multiplan.aqe_mode
указана пустая строка. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.max_stats
(integer
) #Задаёт максимальное количество статистических значений, которые могут храниться в представлении
pgpro_multiplan_stats
. Дальнейшая статистика будет игнорироваться. Значение по умолчанию — 5000. Этот параметр можно задать только при запуске сервера.pgpro_multiplan.max_items
(integer
) #Задаёт максимальное количество записей, с которым может работать pgpro_multiplan. Значение по умолчанию — 100. Этот параметр можно задать только при запуске сервера.
pgpro_multiplan.auto_tracking
(boolean
) #Позволяет pgpro_multiplan автоматически нормализовать и регистрировать запросы, выполняемые с использованием команды
EXPLAIN
. Значение по умолчанию —off
. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.max_local_cache_size
(integer
) #Задаёт максимальный размер локального кеша, в килобайтах. Значение по умолчанию —
0
, что означает отсутствие ограничений. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.wal_rw
(boolean
) #Включает физическую репликацию данных pgpro_multiplan. При значении
off
на главном сервере данные на резервный сервер не передаются. При значенииoff
на резервном сервере любые данные, передаваемые с главного сервера, игнорируются. Значение по умолчанию —off
. Этот параметр можно задать только при запуске сервера.pgpro_multiplan.auto_capturing
(boolean
) #Включает автоматическое отслеживание запросов в pgpro_multiplan. Если для этого параметра конфигурации установить значение
on
, в представлении pgpro_multiplan_captured_queries можно будет увидеть запросы с константами в текстовой форме и параметризованные запросы. Также будут видны все планы для каждого запроса. Информация о выполненных запросах хранится до перезапуска сервера. Значение по умолчанию —off
. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.max_captured_items
(integer
) #Задаёт максимальное количество запросов, которые может отслеживать pgpro_multiplan. Значение по умолчанию — 1000. Этот параметр можно задать только при запуске сервера.
pgpro_multiplan.sandbox
(boolean
) #Включает резервирование отдельных зон разделяемой памяти для ведущего и резервного узла, что позволяет тестировать и анализировать запросы с существующим набором данных без влияния на работу узла. Если на резервном узле установлено значение
on
, pgpro_multiplan замораживает планы выполнения запросов только на этом узле и хранит их в альтернативном хранилище планов — «песочнице». Если параметр включён на ведущем узле, расширение использует отдельную зону разделяемой памяти, данные которой не реплицируются на резервные узлы. При изменении значения параметра сбрасывается кеш pgpro_multiplan. Значение по умолчанию —off
. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.wildcards
(string
) #Разделённый запятыми список регулярных выражений
POSIX
, который служит шаблоном для проверки имён таблиц, содержащихся в запросе. Шаблоны, используемые для сопоставления имён таблиц, хранятся в планах, замороженных как планыtemplate
. Значение по умолчанию —.*
, которое соответствует любому имени таблицы. Регулярные выражения применяются слева направо. Например, в^t[[:digit:]]$,^t.*,.*
первое проверенное регулярное выражение —^t[[:digit:]]$
, следующее —^t.*
, и последнее —.*
.pgpro_multiplan.aqe_max_items
(integer
) #Задаёт максимальное количество значений триггеров перепланирования запросов в реальном времени, которые могут храниться в представлении
aqe_triggers
. Значение по умолчанию — 100. Этот параметр можно задать только при запуске сервера.pgpro_multiplan.aqe_max_stats
(integer
) #Задаёт максимальное количество статистических значений перепланирования запросов в реальном времени, которые могут храниться в представлении
aqe_stats
. Дальнейшие статистические значения будут игнорироваться. Значение по умолчанию — 5000. Этот параметр можно задать только при запуске сервера.