Расширение pgpro_multiplan позволяет пользователю сохранять планы выполнения запросов и использовать эти планы при последующем выполнении тех же запросов, что помогает избежать повторной оптимизации идентичных запросов.
pgpro_multiplan действует подобно системе Oracle Outline. С его помощью можно жёстко зафиксировать план выполнения, если нужен вариант, отличный от предлагаемого планировщиком.
Расширение 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, иначе репликация может работать некорректно.
Расширение pgpro_multiplan можно использовать двумя способами: либо с замороженными, либо с разрешёнными планами.
Расширение pgpro_multiplan позволяет замораживать планы запросов для дальнейшего использования. Заморозка состоит из трёх этапов:
Регистрация запроса, план которого необходимо заморозить.
Изменение плана выполнения запроса.
Заморозка плана выполнения запроса.
Зарегистрировать запрос можно двумя способами:
С помощью функции pgpro_multiplan_register_query():
SELECT pgpro_multiplan_register_query(query_string,parameter_type, ...);
Здесь query_string — запрос с параметрами $ (аналогично nPREPARE ). Можно описать каждый тип параметра, используя необязательный аргумент функции 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))План выполнения запроса можно изменить при помощи переменных оптимизатора, указаний pg_hint_plan при включённом расширении или других расширений, например aqo. Информация о совместимости pgpro_multiplan с другими расширениями представлена в Подразделе G.2.5.
Для заморозки плана выполнения запроса используйте функцию pgpro_multiplan_freeze. Для необязательного параметра plan_type можно задать значение serialized или hintset. Значение по умолчанию — serialized. Более подробно типы замороженных планов описаны в Подразделе G.2.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)Если для данного запроса нет замороженного плана, расширение pgpro_multiplan может применить план из набора разрешённых планов, созданных стандартным планировщиком.
Чтобы добавить план, созданный стандартным планировщиком, в набор разрешённых планов, выполните следующие действия:
Для последующих запросов созданный план применяется без изменений, если он есть в наборе разрешённых планов. Если такого плана нет, то используется самый дешёвый план из набора разрешённых.
Разрешённые планы могут использоваться только при работающем расширении pg_hint_plan, см. разделы Типы замороженных планов и Совместимость с другими расширениями. Разрешённые планы не используются, если включён автоматический захват. Не забудьте отключить параметр pgpro_multiplan.auto_capturing после выполнения захвата.
С помощью параметра 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';Чтобы одобрить любой план из представления 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")Ниже показан пример использования разрешённых планов.
-- Включите параметр 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)Есть три типа замороженных планов: сериализованные, планы с указаниями и планы с шаблонами.
Сериализованный план (serialized) — это сериализованное представление плана. Этот план становится выполняемым планом при первом нахождении соответствующего замороженного запроса. Сериализованный план действителен до тех пор, пока не изменятся метаданные запроса (структуры таблиц, индексы и так далее). В случае пересоздания таблицы, которая присутствует в замороженном плане, данный замороженный план становится недействительным и игнорируется. Сериализованный план действителен только в текущей базе данных и не может быть скопирован в другую, поскольку зависит от идентификаторов объектов. По этой причине использовать сериализованные планы для временных таблиц не имеет смысла.
План hintset — это план с набором указаний, формируемым в момент заморозки на основе плана выполнения. Этот набор состоит из значений переменных окружения оптимизатора, отличных от используемых по умолчанию, типов соединений, порядка соединений и методов доступа к данным. Указания соответствуют указаниям, которые поддерживаются расширением pg_hint_plan. Для использования таких планов необходимо включить расширение pg_hint_plan. Набор указаний передаётся планировщику pg_hint_plan при первом нахождении соответствующего замороженного запроса, после чего pg_hint_plan формирует выполняемый план. В случае отсутствия данного расширения указания игнорируются и выполняется план, сформированный оптимизатором Postgres Pro. План с указаниями не зависит от идентификаторов объектов и остаётся действительным при пересоздании таблиц, добавлении полей и других изменениях. На данный момент разрешённые планы могут быть только типа hintset.
План template — это частный случай плана hintset. Если для сопоставления имён таблиц в запросах и замороженном запросе используются одни и те же регулярные выражения POSIX, используется план template.
Для обеспечения совместимости 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'
Замороженный запрос в текущей БД идентифицируется уникальной парой sql_hash и const_hash.
sql_hash — это хеш, сформированный на основе дерева разбора без учёта параметров и констант. Псевдонимы полей и таблиц не игнорируются, поэтому один и тот же запрос с разными псевдонимами будет иметь разные значения sql_hash.
const_hash — хеш, сгенерированный на основе всех присутствующих в запросе констант. Константы с одинаковым значением, но разным типом, например 1 и '1', выдадут разное значение хеша.
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)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 для остальных типов планов |
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 | Набор указаний, сформированный на основе замороженного плана |
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 |
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 | Счётчик использования замороженных операторов |
Вызывать нижеуказанные функции может только суперпользователь.
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. Функция возвращает количество удалённых записей.
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.*, и последнее — .*.