G.3. pgpro_multiplan — сохранение планов выполнения запросов для последующего использования

G.3.1. Описание

Расширение pgpro_multiplan позволяет сохранять планы выполнения запросов и использовать эти планы при последующем выполнении тех же запросов, что помогает избежать повторной оптимизации идентичных запросов. Можно также использовать это расширение для фиксации определённого плана выполнения, если план, выбранный планировщиком, по каким-то причинам вам не подходит.

pgpro_multiplan работает подобно Oracle SQL Plan Management.

G.3.2. Установка

Расширение pgpro_multiplan предоставляется вместе с Postgres Pro Enterprise в виде отдельного пакета pgpro-multiplan-ent-15 (подробные инструкции по установке приведены в Главе 17). Чтобы включить pgpro_multiplan, выполните следующие действия:

  1. Добавьте имя библиотеки в переменную shared_preload_libraries в файле postgresql.conf:

    shared_preload_libraries = 'pgpro_multiplan'

    Обратите внимание, что имена библиотек в переменной shared_preload_libraries должны добавляться в определённом порядке. Совместимость pgpro_multiplan с другими расширениями описана в Подразделе G.3.7.

  2. Перезагрузите сервер баз данных, чтобы изменения вступили в силу.

    Чтобы убедиться, что библиотека pgpro_multiplan установлена правильно, вы можете выполнить следующую команду:

    SHOW shared_preload_libraries;
  3. Создайте расширение pgpro_multiplan, выполнив следующий запрос:

    CREATE EXTENSION pgpro_multiplan;

    Расширение pgpro_multiplan использует кеш разделяемой памяти, который инициализируется только при запуске сервера, поэтому данная библиотека также должна предзагружаться при запуске. Расширение pgpro_multiplan следует создать в каждой базе данных, где требуется управление запросами.

  4. Включите расширение pgpro_multiplan, которое выключено по умолчанию. Для этого укажите необходимые режимы в параметре pgpro_multiplan.mode. За дополнительной информацией обратитесь к разделу Поддерживаемые режимы и типы планов.

    Включить pgpro_multiplan можно одним из следующих способов:

    • Чтобы активировать расширение для всех серверов, задайте параметр pgpro_multiplan.mode в файле postgresql.conf.

    • Чтобы активировать расширение в текущем сеансе, используйте следующую команду:

      SET pgpro_multiplan.mode = 'frozen';
  5. При необходимости переноса данных 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.

Чтобы заморозить план для дальнейшего использования, выполните следующие шаги:

  1. Зарегистрируйте запрос, план которого необходимо заморозить.

  2. Измените план выполнения запроса.

  3. Заморозьте план выполнения запроса.

G.3.4.1. Регистрация запроса

Зарегистрировать запрос можно следующими способами:

  • С помощью функции pgpro_multiplan_register_query():

    SELECT pgpro_multiplan_register_query(query_string, parameter_type, ...);

    Здесь query_string — запрос с параметрами $n (аналогично PREPARE statement_name AS). Можно описать каждый тип параметра, используя необязательный аргумент функции parameter_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.

Чтобы добавить план, созданный стандартным планировщиком, в набор разрешённых планов, выполните следующие действия:

Для последующих запросов созданный план применяется без изменений, если он есть в наборе разрешённых планов. Если такого плана нет, то используется самый дешёвый план из набора разрешённых.

Примечание

Разрешённые планы могут использоваться только при работающем расширении 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. Обновление версии сервера

Выполните шаги ниже, чтобы сохранить замороженные планы при обновлении сервера со старой версии с несовместимым хранилищем данных.

  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';
  2. Обновите версию сервера.

  3. Восстановите замороженные планы.

    SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type)
    FROM storage_copy;
G.3.6.2.2. Перенос планов между экземплярами серверов

Чтобы перенести замороженные планы между двумя серверами, выполните следующее:

  1. Подключитесь к исходному серверу.

  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';
      
  3. Используйте утилиту pg_dump, чтобы выгрузить таблицу в файл.

    $ pg_dump --table storage_copy -Ft postgres > storage_copy.tar
  4. Подключитесь к целевому серверу и нужной базе данных.

  5. Переместите созданный файл выгрузки в целевую файловую систему.

  6. Используйте утилиту pg_restore, чтобы восстановить таблицу с замороженными планами из файла выгрузки.

    $ pg_restore --dbname postgres -Ft storage_copy.tar
  7. Восстановите замороженные планы.

    SELECT pgpro_multiplan_restore(query_string, hintstr, paramtypes, plan_type)
    FROM storage_copy;
    
    DROP TABLE storage_copy;
G.3.6.2.3. Перенос планов из "песочницы" в обычное хранилище

Чтобы перенести замороженные планы из "песочницы" в обычное хранилище, выполните следующие шаги:

  1. Установите параметру 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';
  2. Установите для параметра 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. Статистика

Чтобы собирать статистику об использовании замороженных и разрешённых планов, укажите значение 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.11. Представления

G.3.11.1. Представление pgpro_multiplan_storage

Представление pgpro_multiplan_storage содержит подробную информацию обо всех замороженных и разрешённых планах. Столбцы представления показаны в Таблице G.2.

Таблица G.2. Столбцы pgpro_multiplan_storage

ИмяТипОписание
dbidoidИдентификатор базы данных, в которой выполнялся оператор
sql_hashbigintВнутренний идентификатор запроса
const_hashbigintХеш непараметризованных констант
plan_hashbigintВнутренний идентификатор разрешённого плана, 0 — для замороженных планов
validbooleanFALSE, если план был аннулирован при последнем использовании
costfloatСтоимость разрешённого плана, 0 — для замороженных планов
sample_stringtextНепараметризованный запрос с константами, для которого план был заморожен или добавлен в список разрешённых
query_stringtextПараметризованный запрос, для которого план был заморожен или добавлен в список разрешённых
paramtypesregtype[]Массив с типами параметров, использованными в запросе
querytextВнутреннее представление запроса
plantextВнутреннее представление плана
plan_typetextТип плана. Для замороженных планов: serialized, hintset или template. Для разрешённых планов: baseline
hintstrtextНабор указаний, сформированный на основе плана
wildcardstextШаблоны, используемые для замороженного плана template, NULL для остальных типов планов

G.3.11.2. Представление pgpro_multiplan_local_cache

Представление pgpro_multiplan_local_cache содержит подробную информацию о зарегистрированных и замороженных операторах в локальном кеше. Столбцы представления показаны в Таблице G.3.

Таблица G.3. Столбцы pgpro_multiplan_local_cache

ИмяТипОписание
sql_hashbigintВнутренний идентификатор запроса
const_hashbigintХеш непараметризованных констант
fs_is_frozenbooleanTRUE, если оператор был заморожен
fs_is_validbooleanTRUE, если оператор действителен
ps_is_validbooleanTRUE, если оператор должен быть перепроверен
query_stringtextЗапрос, зарегистрированный функцией pgpro_multiplan_register_query
querytextВнутреннее представление запроса
paramtypesregtype[]Массив с типами параметров, использованными в запросе
hintstrtextНабор указаний, сформированный на основе замороженного плана

G.3.11.3. Представление pgpro_multiplan_captured_queries

Представление pgpro_multiplan_captured_queries содержит подробную информацию обо всех запросах, отслеживаемых в сеансах. Столбцы представления показаны в Таблице G.4.

Таблица G.4. Столбцы pgpro_multiplan_captured_queries

ИмяТипОписание
dbidoidИдентификатор базы данных, в которой выполнялся оператор
sql_hashbigintВнутренний идентификатор запроса
queryidbigintСтандартный идентификатор запроса
plan_hashbigintВнутренний идентификатор плана
planidbigintИдентификатор плана, совместимый с расширением pgpro_stats
costfloatСтоимость плана
sample_stringtextНепараметризованный запрос с константами
query_stringtextПараметризованный запрос
constantstextНабор констант в запросе
prep_conststextНабор констант, использованных для выполнения (EXECUTE) подготовленного оператора
hintstrtextНабор указаний, сформированный на основе плана
explain_plantextПлан, показанный командой EXPLAIN

G.3.11.4. Представление pgpro_multiplan_stats

Представление pgpro_multiplan_stats предоставляет статистику использования замороженных и разрешённых планов. Столбцы представления показаны в Таблице G.5.

Таблица G.5. Столбцы pgpro_multiplan_stats

ИмяТипОписание
dbidoidИдентификатор базы данных, в которой выполнялся оператор
sql_hashbigintВнутренний идентификатор запроса
plan_hashbigintВнутренний идентификатор плана
planidbigintИдентификатор плана, совместимый с расширением pgpro_stats
counterbigintКоличество использований плана

G.3.12. Функции

Вызывать нижеуказанные функции могут только суперпользователи.

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) для указанного запроса.

pgpro_multiplan_restore(query_string text, hintstr texttext, paramtypes regtype[], plan_type text) returns record

Восстанавливает замороженный план для указанного запроса в текущую базу данных.

Эта функция имеет следующие аргументы:

  • query_string: Запрос с параметрами $n (аналогично PREPARE statement_name AS), для которого восстанавливается замороженный план на основе набора указаний.

  • hintstr: Набор указаний, поддерживаемых расширением pg_hint_plan. Если для аргумента указано значение NULL или пустая строка, будет использоваться стандартный план.

  • parameter_type: Массив с типами параметров, используемых в запросе. Если для аргумента указано значение NULL, типы параметров должны быть определены автоматически.

  • plan_type: Тип плана. Допустимые значения: serialized и hintset. План с типом template не поддерживается.

Функция возвращает уникальную пару sql_hash и const_hash, если план был успешно восстановлен. В противном случае, она возвращает NULL.

G.3.13. Параметры конфигурации

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.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.*, и последнее — .*.