G.2. pgpro_multiplan — сохранение отдельных планов параметризованных запросов для использования в будущем #
G.2.1. Описание #
Расширение pgpro_multiplan позволяет пользователю сохранять планы выполнения запросов и использовать эти планы при последующем выполнении тех же запросов, что помогает избежать повторной оптимизации идентичных запросов.
pgpro_multiplan действует подобно системе Oracle Outline. С его помощью можно жёстко зафиксировать план выполнения, если нужен вариант, отличный от предлагаемого планировщиком.
G.2.2. Установка #
Расширение pgpro_multiplan
предоставляется вместе с Postgres Pro Enterprise в виде отдельного пакета pgpro-multiplan-ent-17
(подробные инструкции по установке приведены в Главе 17). Чтобы включить pgpro_multiplan
, выполните следующие действия:
Добавьте имя библиотеки в переменную
shared_preload_libraries
в файлеpostgresql.conf
:shared_preload_libraries = 'pgpro_multiplan'
Обратите внимание, что имена библиотек в переменной
shared_preload_libraries
должны добавляться в определённом порядке. Совместимость pgpro_multiplan с другими расширениями описана в Подразделе G.2.5.Перезагрузите сервер баз данных, чтобы изменения вступили в силу.
Чтобы убедиться, что библиотека
pgpro_multiplan
установлена правильно, вы можете выполнить следующую команду:SHOW shared_preload_libraries;
Создайте расширение
pgpro_multiplan
, выполнив следующий запрос:CREATE EXTENSION pgpro_multiplan;
Расширение pgpro_multiplan использует кеш разделяемой памяти, который инициализируется только при запуске сервера, поэтому данная библиотека также должна предзагружаться при запуске. Расширение pgpro_multiplan следует создать в каждой базе данных, где требуется управление запросами.
По умолчанию расширение pgpro_multiplan выключено. Включить его можно одним из следующих способов:
Чтобы включить pgpro_multiplan для всех серверов, в файле
postgresql.conf
необходимо указатьpgpro_multiplan.enable = true
.Чтобы включить pgpro_multiplan в текущем сеансе, воспользуйтесь следующей командой:
SET pgpro_multiplan.enable TO true;
При необходимости переноса данных pgpro_multiplan с главного на резервный сервер при помощи физической репликации, на обоих серверах необходимо задать значение параметра pgpro_multiplan.wal_rw=
on
. Также убедитесь, что на обоих серверах установлена одинаковая версия pgpro_multiplan, иначе репликация может работать некорректно.
G.2.3. Использование #
Расширение pgpro_multiplan можно использовать двумя способами: либо с замороженными, либо с разрешёнными планами.
G.2.3.1. Замороженные планы #
Расширение pgpro_multiplan позволяет замораживать планы запросов для дальнейшего использования. Заморозка состоит из трёх этапов:
Регистрация запроса, план которого необходимо заморозить.
Изменение плана выполнения запроса.
Заморозка плана выполнения запроса.
G.2.3.1.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 -> 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))
G.2.3.1.2. Изменение плана выполнения запроса #
План выполнения запроса можно изменить при помощи переменных оптимизатора, указаний pg_hint_plan при включённом расширении или других расширений, например aqo. Информация о совместимости pgpro_multiplan с другими расширениями представлена в Подразделе G.2.5.
G.2.3.1.3. Заморозка плана выполнения запроса #
Для заморозки плана выполнения запроса используйте функцию pgpro_multiplan_freeze. Для необязательного параметра plan_type
можно задать значение serialized
или hintset
. Значение по умолчанию — serialized
. Более подробно типы замороженных планов описаны в Подразделе G.2.4.
G.2.3.1.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.enable = 'on'; -- Зарегистрируйте запрос 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) -- Измените план выполнения запроса -- Запустите сканирование индекса, отключив последовательное сканирование 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; SET enable_seqscan = 'off'; -- Заморозьте план выполнения запроса 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.2.3.2. Разрешённые планы #
Если для данного запроса нет замороженного плана, расширение pgpro_multiplan может применить план из набора разрешённых планов, созданных стандартным планировщиком.
Чтобы добавить план, созданный стандартным планировщиком, в набор разрешённых планов, выполните следующие действия:
Для последующих запросов созданный план применяется без изменений, если он есть в наборе разрешённых планов. Если такого плана нет, то используется самый дешёвый план из набора разрешённых.
Примечание
Разрешённые планы могут использоваться только при работающем расширении pg_hint_plan, см. разделы Типы замороженных планов и Совместимость с другими расширениями. Разрешённые планы не используются, если включён автоматический захват. Не забудьте отключить параметр pgpro_multiplan.auto_capturing после выполнения захвата.
G.2.3.2.1. Захват плана #
С помощью параметра pgpro_multiplan.auto_capturing можно включить захват всех выполняемых запросов.
-- Создайте таблицу '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.auto_capturing = 'on'; SET pgpro_multiplan.enable = '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.2.3.2.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 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 | <> hintstr | Leading(("t1" "t2" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") SeqScan("t1") -[ RECORD 2 ]+------------------------------------------------------------------------------------------------ dbid | 5 sql_hash | 6079808577596655075 const_hash | 0 plan_hash | 2719320099967191582 valid | t cost | 18.997500000000002 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 | <> hintstr | Leading(("t2" "t1" )) HashJoin("t1" "t2") IndexScan("t2" "a_y_idx") IndexScan("t1" "a_y_idx")
G.2.3.2.3. Пример разрешённого плана #
Ниже показан пример использования разрешённых планов.
-- Включите параметр auto_capturing SET pgpro_multiplan.auto_capturing = 'on'; SET pgpro_multiplan.enable = '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: frozen, hintset 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: frozen, hintset 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.2.4. Типы замороженных планов #
Есть три типа замороженных планов: сериализованные, планы с указаниями и планы с шаблонами.
Сериализованный план (
serialized
) — это сериализованное представление плана. Этот план становится выполняемым планом при первом нахождении соответствующего замороженного запроса. Сериализованный план действителен до тех пор, пока не изменятся метаданные запроса (структуры таблиц, индексы и так далее). В случае пересоздания таблицы, которая присутствует в замороженном плане, данный замороженный план становится недействительным и игнорируется. Сериализованный план действителен только в текущей базе данных и не может быть скопирован в другую, поскольку зависит от идентификаторов объектов. По этой причине использовать сериализованные планы для временных таблиц не имеет смысла.План
hintset
— это план с набором указаний, формируемым в момент заморозки на основе плана выполнения. Этот набор состоит из значений переменных окружения оптимизатора, отличных от используемых по умолчанию, типов соединений, порядка соединений и методов доступа к данным. Указания соответствуют указаниям, которые поддерживаются расширением pg_hint_plan. Для использования таких планов необходимо включить расширение pg_hint_plan. Набор указаний передаётся планировщику pg_hint_plan при первом нахождении соответствующего замороженного запроса, после чего pg_hint_plan формирует выполняемый план. В случае отсутствия данного расширения указания игнорируются и выполняется план, сформированный оптимизатором Postgres Pro. План с указаниями не зависит от идентификаторов объектов и остаётся действительным при пересоздании таблиц, добавлении полей и других изменениях. На данный момент разрешённые планы могут быть только типаhintset
.План
template
— это частный случай планаhintset
. Если для сопоставления имён таблиц в запросах и замороженном запросе используются одни и те же регулярные выраженияPOSIX
, используется планtemplate
.
G.2.5. Совместимость с другими расширениями #
Для обеспечения совместимости 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.2.6. Идентификация замороженного запроса #
Замороженный запрос в текущей БД идентифицируется уникальной парой sql_hash
и const_hash
.
sql_hash
— это хеш, сформированный на основе дерева разбора без учёта параметров и констант. Псевдонимы полей и таблиц не игнорируются, поэтому один и тот же запрос с разными псевдонимами будет иметь разные значения sql_hash
.
const_hash
— хеш, сгенерированный на основе всех присутствующих в запросе констант. Константы с одинаковым значением, но разным типом, например 1
и '1'
, выдадут разное значение хеша.
G.2.7. Автоматическое приведение типов #
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.2.8. Представления #
G.2.8.1. Представление pgpro_multiplan_storage
#
Представление pgpro_multiplan_storage
содержит подробную информацию обо всех замороженных операторах. Столбцы представления показаны в Таблице G.2.
Таблица G.2. Столбцы pgpro_multiplan_storage
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
const_hash | bigint | Хеш непараметризованных констант |
valid | boolean | FALSE , если план был аннулирован при последнем использовании |
query_string | text | Запрос, зарегистрированный функцией pgpro_multiplan_register_query |
paramtypes | regtype[] | Массив с типами параметров, использованными в запросе |
query | text | Внутреннее представление запроса |
plan | text | Внутреннее представление плана |
plan_type | text | Тип плана: serialized , hintset или template |
hintstr | text | Набор указаний, сформированный на основе замороженного плана |
wildcards | text | Шаблоны, используемые для плана template , NULL для остальных типов планов |
G.2.8.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.2.8.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 | Внутренний идентификатор плана |
sample_string | text | Запрос, выполненный в режиме автоматического отслеживания запросов |
query_string | text | Параметризованный запрос |
constants | text | Набор констант в запросе |
prep_consts | text | Набор констант, использованных для выполнения (EXECUTE ) подготовленного оператора |
hintstr | text | Набор указаний, сформированный на основе плана |
explain_plan | text | План, показанный командой EXPLAIN |
G.2.8.4. Представление pgpro_multiplan_fs_counter
#
Представление pgpro_multiplan_fs_counter
содержит информацию о замороженных операторах. Столбцы представления показаны в Таблице G.5.
Таблица G.5. Столбцы pgpro_multiplan_fs_counter
Имя | Тип | Описание |
---|---|---|
dbid | oid | Идентификатор базы данных, в которой выполнялся оператор |
sql_hash | bigint | Внутренний идентификатор запроса |
plan_hash | bigint | Внутренний идентификатор плана |
usage_numb | text | Счётчик использования замороженных операторов |
G.2.9. Функции #
Вызывать нижеуказанные функции может только суперпользователь.
-
pgpro_multiplan_register_query(
query_string
text
) returns record
pgpro_multiplan_register_query(
#query_string
text
,VARIADIC
regtype[]
) returns record Сохраняет запрос, описанный в
query_string
, в локальном кеше и возвращает уникальную паруsql_hash
иconst_hash
.-
pgpro_multiplan_unregister_query() returns bool
# Удаляет из локального кеша запрос, который был зарегистрирован, но не был заморожен. Если нет ошибок, возвращает true.
-
pgpro_multiplan_freeze(
#plan_type
text
) returns bool Замораживает последний использованный план для оператора. Допустимые значения необязательного аргумента
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 Удаляет план только из хранилища, но оставляет запрос в локальном кеше. Если нет ошибок, возвращает 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 для указанной базы данных. Чтобы удалить данные, собранные pgpro_multiplan для текущей базы данных, не указывайте
dbid
. Чтобы сбросить данные для всех баз данных, установите для параметраdbid
значение NULL.-
pgpro_multiplan_reload_frozen_plancache() returns bool
# Удаляет все замороженные планы и снова загружает их из хранилища. Также удаляет операторы, которые были зарегистрированы, но не заморожены.
-
pgpro_multiplan_fs_counter() returns table
# Возвращает
plan_hash
замороженного плана, количество использований каждого замороженного оператора и идентификатор базы данных, в которой этот оператор был зарегистрирован и использован. Если замороженный план изменился, статистика использования замороженных операторов сбрасывается и пересчитывается с использованием новогоplan_hash
.-
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. Возвращает true, если запрос был успешно перемещён.
-
pgpro_multiplan_set_plan_type(
#sql_hash
bigint
,const_hash
bigint
,plan_type
text
) returns bool Устанавливает тип плана запроса для замороженного оператора. Допустимые значения аргумента
plan_type
:serialized
иhintset
. Чтобы иметь возможность использовать план запроса типаhintset
, необходимо загрузить модуль 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. Функция возвращает количество удалённых записей.
G.2.10. Параметры конфигурации #
pgpro_multiplan.enable
(boolean
) #Позволяет pgpro_multiplan использовать замороженные планы. Значение по умолчанию —
off
. Изменить этот параметр могут только суперпользователи.pgpro_multiplan.fs_ctr_max
(integer
) #Задаёт максимальное количество замороженных операторов, возвращаемых функцией
pgpro_multiplan_fs_counter()
. Значение по умолчанию — 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.*
, и последнее —.*
.