F.40. pg_hint_plan#

F.40. pg_hint_plan

F.40. pg_hint_plan

F.40.1. О расширении pg_hint_plan

Версия: 1.5.0

GitHub

Авторское право (c) 2012-2023, КОРПОРАЦИЯ NIPPON TELEGRAPH AND TELEPHONE

F.40.2. Описание

pg_hint_plan позволяет настраивать планы выполнения Tantor SE с использованием так называемых подсказок в комментариях SQL, например /*+ SeqScan(a) */.

Tantor SE использует оптимизатор на основе стоимости, который использует статистику данных, а не статические правила. Планировщик (оптимизатор) оценивает стоимость каждого возможного плана выполнения для SQL-запроса, затем план выполнения с наименьшей стоимостью в конечном итоге выполняется. Планировщик делает все возможное, чтобы выбрать наилучший план выполнения, но не всегда получается выбрать оптимальный план, поскольку он не учитывает некоторые свойства данных, например, корреляцию между столбцами.

F.40.3. Описание

F.40.3.1. Основное использование

pg_hint_plan читает подсказки, записанные в комментариях специального формата, целевые SQL-операторы. Специальный формат начинается с последовательности символов "/\*+" и заканчивается "\*/". Подсказки состоят из имени подсказки и следующих параметров, заключенных в скобки и разделенных пробелами. Каждая подсказка может быть разделена на несколько строк для удобочитаемости.

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

F.40.4. Таблица подсказок

Подсказки описаны в комментарии в специальной форме в вышеуказанном разделе. Это неудобно в случае, когда запросы не могут быть отредактированы. В этом случае подсказки могут быть размещены в специальной таблице под названием "hint_plan.hints". Таблица состоит из следующих столбцов.

столбец описание
id Уникальный номер для идентификации строки подсказки. Эта колонка заполняется автоматически по последовательности.
norm_query_string Шаблон соответствует запросу, который должен быть подсказан. Константы в запросе должны быть заменены на ?, как в следующем примере. Пробелы важны в шаблоне.
application_name Значение application_name сессий для применения подсказки. Подсказка в примере ниже применяется к сессиям, подключенным от psql. Пустая строка означает сессии любого application_name.
hints Фраза подсказки. Это должна быть серия подсказок, исключая окружающие знаки комментариев.

Следующий пример показывает, как работать с таблицей подсказок.

postgres=# INSERT INTO hint_plan.hints(norm_query_string, application_name, hints)
postgres-#     VALUES (
postgres(#         'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
postgres(#         '',
postgres(#         'SeqScan(t1)'
postgres(#     );
INSERT 0 1
postgres=# UPDATE hint_plan.hints
postgres-#    SET hints = 'IndexScan(t1)'
postgres-#  WHERE id = 1;
UPDATE 1
postgres=# DELETE FROM hint_plan.hints
postgres-#  WHERE id = 1;
DELETE 1
postgres=#

Таблица подсказок принадлежит пользователю-создателю и имеет привилегии по умолчанию на момент создания. во время CREATE EXTENSION. Подсказки таблицы имеют приоритет над комментариями.

F.40.4.1. Типы подсказок

Подсказки фразы классифицируются на шесть типов в зависимости от того, какой объект и как они могут влиять на планирование. Методы сканирования, методы соединения, порядок соединения, коррекция номера строки, параллельный запрос и настройка GUC. Вы увидите списки фраз-подсказок каждого типа в списке подсказок.

F.40.4.1.1. Подсказки для методов сканирования

Подсказки метода сканирования накладывают определенный метод сканирования на целевую таблицу. pg_hint_plan распознает целевую таблицу по псевдонимам, если они есть. Они могут быть SeqScan, IndexScan и так далее в этом типе подсказки.

Подсказки сканирования эффективны для обычных таблиц, таблиц наследования, незафиксированных таблиц, временных таблиц и системных каталогов. Внешние таблицы, таблицы-функции, предложения VALUES, общие табличные выражения (CTE), представления и подзапросы не затрагиваются.

postgres=# /*+
postgres*#     SeqScan(t1)
postgres*#     IndexScan(t2 t2_pkey)
postgres*#  */
postgres-# SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key);
F.40.4.1.2. Подсказки по методам соединения

Подсказки метода соединения обеспечивают использование определенных методов соединения для соединений, включающих указанные таблицы.

Это может повлиять только на соединения обычных таблиц, таблиц наследования, незафиксированных таблиц, временных таблиц, внешних таблиц, системных каталогов, таблиц-функций, результаты команды VALUES и CTE могут быть в списке параметров. Однако соединения с представлениями и подзапросами не затрагиваются.

F.40.4.1.3. Подсказка для порядка соединения

Эта подсказка Leading обеспечивает порядок соединения двух или более таблиц. Существует два способа обеспечения порядка. Один из них обеспечивает конкретный порядок соединения, но не ограничивает направление на каждом уровне соединения. Другой также обеспечивает направление соединения. Подробности можно увидеть в таблице списка подсказок.

postgres=# /*+
postgres*#     NestLoop(t1 t2)
postgres*#     MergeJoin(t1 t2 t3)
postgres*#     Leading(t1 t2 t3)
postgres*#  */
postgres-# SELECT * FROM table1 t1
postgres-#     JOIN table table2 t2 ON (t1.key = t2.key)
postgres-#     JOIN table table3 t3 ON (t2.key = t3.key);
F.40.4.1.4. Подсказка для коррекции номера строки

Эта подсказка Rows исправляет неправильную оценку номера строки, которая возникает из-за ограничений планировщика.

postgres=# /*+ Rows(a b #10) */ SELECT... ; Sets rows of join result to 10
postgres=# /*+ Rows(a b +10) */ SELECT... ; Increments row number by 10
postgres=# /*+ Rows(a b -10) */ SELECT... ; Subtracts 10 from the row number.
postgres=# /*+ Rows(a b *10) */ SELECT... ; Makes the number 10 times larger.
F.40.4.1.5. Подсказка для параллельного плана

Эта подсказка Parallel принуждает параллельную конфигурацию выполнения при сканировании. Третий параметр указывает на силу принуждения. soft означает, что pg_hint_plan изменяет только max_parallel_worker_per_gather и оставляет все остальные параметры планировщика. hard изменяет другие параметры планировщика, чтобы принудительно применить это число. Это может повлиять на обычные таблицы, родительские таблицы, непротоколируемые таблицы и системные каталоги. Внешние таблицы, таблицы функций, значения, общие табличные выражения, представления и подзапросы не затрагиваются. Внутренние таблицы представления можно указать по его реальному имени/псевдониму в качестве целевого объекта. В следующем примере показано, что запрос принуждается по-разному для каждой таблицы.

postgres=# explain /*+ Parallel(c1 3 hard) Parallel(c2 5 hard) */
       SELECT c2.a FROM c1 JOIN c2 ON (c1.a = c2.a);
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Hash Join  (cost=2.86..11406.38 rows=101 width=4)
   Hash Cond: (c1.a = c2.a)
   ->  Gather  (cost=0.00..7652.13 rows=1000101 width=4)
         Workers Planned: 3
         ->  Parallel Seq Scan on c1  (cost=0.00..7652.13 rows=322613 width=4)
   ->  Hash  (cost=1.59..1.59 rows=101 width=4)
         ->  Gather  (cost=0.00..1.59 rows=101 width=4)
               Workers Planned: 5
               ->  Parallel Seq Scan on c2  (cost=0.00..1.59 rows=59 width=4)

postgres=# EXPLAIN /*+ Parallel(tl 5 hard) */ SELECT sum(a) FROM tl;
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Finalize Aggregate  (cost=693.02..693.03 rows=1 width=8)
   ->  Gather  (cost=693.00..693.01 rows=5 width=8)
         Workers Planned: 5
         ->  Partial Aggregate  (cost=693.00..693.01 rows=1 width=8)
               ->  Parallel Seq Scan on tl  (cost=0.00..643.00 rows=20000 width=4)
F.40.4.1.6. Параметры GUC временно устанавливаются

Set подсказка изменяет параметры GUC только во время планирования. Параметр GUC, показанный в Раздел 19.7 может оказывать ожидаемые воздействия на планирование, если никакая другая подсказка не конфликтует с параметрами конфигурации метода планировщика. Последняя из подсказок по тому же параметру GUC срабатывает. Параметры GUC для pg_hint_plan также могут быть установлены этой подсказкой, но она не будет работать в соответствии с вашими ожиданиями.

postgres=# /*+ Set(random_page_cost 2.0) */
postgres-# SELECT * FROM table1 t1 WHERE key = 'value';
...

F.40.4.2. Параметры GUC для pg_hint_plan

Ниже приведены GUC-параметры, которые влияют на поведение pg_hint_plan.

Название параметра Описание По умолчанию
pg_hint_plan.enable_hint True включает pg_hint_plan. on
pg_hint_plan.enable_hint_table True включает подсказки по таблице. true или false. off
pg_hint_plan.parse_messages Определяет уровень журнала ошибок разбора подсказок. Допустимые значения: error, warning, notice, info, log, debug. INFO
pg_hint_plan.debug_print Контролирует вывод отладочной информации и детальность информации. Допустимые значения - off, on, detailed и verbose. off
pg_hint_plan.message_level Определяет уровень сообщений при выводе отладочной информации. Допустимые значения: error, warning, notice, info, log, debug. INFO

F.40.5. Установка

В этом разделе описываются шаги установки.

F.40.5.1. Загрузка pg_hint_plan

Обычно pg_hint_plan не требует CREATE EXTENSION. Просто загрузите его с помощью команды LOAD, и он активируется, и, конечно, вы можете загрузить его глобально, установив shared_preload_libraries в postgresql.conf. Или вам может подойти вариант использования ALTER USER SET/ALTER DATABASE SET для автоматической загрузки для определенных сессий.

postgres=# LOAD 'pg_hint_plan';
LOAD
postgres=#

Выполните CREATE EXTENSION и SET pg_hint_plan.enable_hint_tables TO on, если вы планируете использовать подсказки для таблиц.

F.40.6. Подробности в подсказке

F.40.6.1. Синтаксис и размещение

pg_hint_plan считывает подсказки только из первого блочного комментария, и любые символы, кроме букв, цифр, пробелов, подчеркиваний, запятых и скобок, прекращают разбор немедленно. В следующем примере HashJoin(a b) и SeqScan(a) разбираются как подсказки, но IndexScan(a) и MergeJoin(a b) - нет.

postgres=# /*+
postgres*#    HashJoin(a b)
postgres*#    SeqScan(a)
postgres*#  */
postgres-# /*+ IndexScan(a) */
postgres-# EXPLAIN SELECT /*+ MergeJoin(a b) */ *
postgres-#    FROM pgbench_branches b
postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
postgres-#   ORDER BY a.aid;
                                      QUERY PLAN
---------------------------------------------------------------------------------------
 Sort  (cost=31465.84..31715.84 rows=100000 width=197)
   Sort Key: a.aid
   ->  Hash Join  (cost=1.02..4016.02 rows=100000 width=197)
         Hash Cond: (a.bid = b.bid)
         ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
         ->  Hash  (cost=1.01..1.01 rows=1 width=100)
               ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
(7 rows)

postgres=#

F.40.6.2. Использование с PL/pgSQL

pg_hint_plan работает для запросов в скриптах PL/pgSQL с некоторыми ограничениями.

  • Подсказки влияют только на следующие типы запросов.

    • Запросы, которые возвращают одну строку. (SELECT, INSERT, UPDATE и DELETE)

    • Запросы, которые возвращают несколько строк. (RETURN QUERY)

    • Динамические SQL-запросы. (EXECUTE)

    • Открыть курсор. (OPEN)

    • Цикл по результату запроса (FOR)

  • Подсказка: комментарий должен быть размещен после первого слова в запросе, как показано ниже, так как предшествующие комментарии не отправляются как часть запроса.

    postgres=# CREATE FUNCTION hints_func(integer) RETURNS integer AS $$
    postgres$# DECLARE
    postgres$#     id  integer;
    postgres$#     cnt integer;
    postgres$# BEGIN
    postgres$#     SELECT /*+ NoIndexScan(a) */ aid
    postgres$#         INTO id FROM pgbench_accounts a WHERE aid = $1;
    postgres$#     SELECT /*+ SeqScan(a) */ count(*)
    postgres$#         INTO cnt FROM pgbench_accounts a;
    postgres$#     RETURN id + cnt;
    postgres$# END;
    postgres$# $$ LANGUAGE plpgsql;
    

F.40.6.3. Регистр букв в именах объектов

В отличие от того, как Tantor SE обрабатывает имена объектов, pg_hint_plan сравнивает чистые имена объектов в подсказках с внутренними именами объектов базы данных с учетом регистра. Поэтому имя объекта TBL в подсказке совпадает только с TBL в базе данных и не совпадает ни с одним не заключенным в кавычки именем, таким как TBL, tbl или Tbl.

F.40.6.4. Экранирование специальных символов в именах объектов

Объекты в качестве параметра подсказки должны быть заключены в двойные кавычки, если они включают скобки, двойные кавычки и пробелы. Правило экранирования такое же, как в Tantor SE.

F.40.6.5. Различие между несколькими вхождениями таблицы

pg_hint_plan идентифицирует целевой объект, используя псевдонимы, если они существуют. Это поведение полезно для указания конкретного вхождения среди нескольких вхождений одной таблицы.

postgres=# /*+ HashJoin(t1 t1) */
postgres-# EXPLAIN SELECT * FROM s1.t1
postgres-# JOIN public.t1 ON (s1.t1.id=public.t1.id);
INFO:  hint syntax error at or near "HashJoin(t1 t1)"
DETAIL:  Relation name "t1" is ambiguous.
...
postgres=# /*+ HashJoin(pt st) */
postgres-# EXPLAIN SELECT * FROM s1.t1 st
postgres-# JOIN public.t1 pt ON (st.id=pt.id);
                             QUERY PLAN
---------------------------------------------------------------------
 Hash Join  (cost=64.00..1112.00 rows=28800 width=8)
   Hash Cond: (st.id = pt.id)
   ->  Seq Scan on t1 st  (cost=0.00..34.00 rows=2400 width=4)
   ->  Hash  (cost=34.00..34.00 rows=2400 width=4)
         ->  Seq Scan on t1 pt  (cost=0.00..34.00 rows=2400 width=4)
F.40.6.5.1. Подлежащие таблицы представлений или правил

Подсказки не применимы к самим представлениям, но они могут влиять на запросы внутри, если имена объектов совпадают с именами объектов в развернутом запросе на представление. Присвоение псевдонимов таблицам в представлении позволяет их манипулировать извне представления.

postgres=# CREATE VIEW v1 AS SELECT * FROM t2;
postgres=# EXPLAIN /*+ HashJoin(t1 v1) */
          SELECT * FROM t1 JOIN v1 ON (c1.a = v1.a);
                            QUERY PLAN
------------------------------------------------------------------
 Hash Join  (cost=3.27..18181.67 rows=101 width=8)
   Hash Cond: (t1.a = t2.a)
   ->  Seq Scan on t1  (cost=0.00..14427.01 rows=1000101 width=4)
   ->  Hash  (cost=2.01..2.01 rows=101 width=4)
         ->  Seq Scan on t2  (cost=0.00..2.01 rows=101 width=4)
F.40.6.5.2. Таблицы наследования

Подсказки могут указывать только на родительскую таблицу наследования, и подсказка влияет на всё наследование. Подсказки, одновременно указывающие непосредственно на дочерние таблицы, не действуют.

F.40.6.5.3. Подсказка по множественным операторам

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

F.40.6.5.4. Значения выражений

Выражения VALUES в предложении FROM внутренне называются *VALUES*, поэтому они могут быть подсказаны, если это единственное VALUES в запросе. Два или более выражения VALUES в запросе кажутся различимыми при просмотре его объяснения. Но на самом деле это всего лишь незначительное изменение и они не различимы.

postgres=# /*+ MergeJoin(*VALUES*_1 *VALUES*) */
      EXPLAIN SELECT * FROM (VALUES (1, 1), (2, 2)) v (a, b)
      JOIN (VALUES (1, 5), (2, 8), (3, 4)) w (a, c) ON v.a = w.a;
INFO:  pg_hint_plan: hint syntax error at or near "MergeJoin(*VALUES*_1 *VALUES*) "
DETAIL:  Relation name "*VALUES*" is ambiguous.
                               QUERY PLAN
-------------------------------------------------------------------------
 Hash Join  (cost=0.05..0.12 rows=2 width=16)
   Hash Cond: ("*VALUES*_1".column1 = "*VALUES*".column1)
   ->  Values Scan on "*VALUES*_1"  (cost=0.00..0.04 rows=3 width=8)
   ->  Hash  (cost=0.03..0.03 rows=2 width=8)
         ->  Values Scan on "*VALUES*"  (cost=0.00..0.03 rows=2 width=8)

F.40.6.6. Подзапросы

Подзапросы в следующем контексте иногда можно подсказать, используя имя ANY_subquery.

IN (SELECT ... {LIMIT | OFFSET ...} ...)
= ANY (SELECT ... {LIMIT | OFFSET ...} ...)
= SOME (SELECT ... {LIMIT | OFFSET ...} ...)

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

postgres=# /*+HashJoin(a1 ANY_subquery)*/
postgres=# EXPLAIN SELECT *
postgres=#    FROM pgbench_accounts a1
postgres=#   WHERE aid IN (SELECT bid FROM pgbench_accounts a2 LIMIT 10);
                                         QUERY PLAN

---------------------------------------------------------------------------------------------
 Hash Semi Join  (cost=0.49..2903.00 rows=1 width=97)
   Hash Cond: (a1.aid = a2.bid)
   ->  Seq Scan on pgbench_accounts a1  (cost=0.00..2640.00 rows=100000 width=97)
   ->  Hash  (cost=0.36..0.36 rows=10 width=4)
         ->  Limit  (cost=0.00..0.26 rows=10 width=4)
               ->  Seq Scan on pgbench_accounts a2  (cost=0.00..2640.00 rows=100000 width=4)
F.40.6.6.1. Используя подсказку IndexOnlyScan

Индексное сканирование может неожиданно выполняться на другом индексе, когда указанный в подсказке IndexOnlyScan индекс не может выполнить только индексное сканирование.

F.40.6.6.2. Поведение NoIndexScan

NoIndexScan hint involes NoIndexOnlyScan.

F.40.6.6.3. Подсказка о параллельном выполнении и UNION

A UNION может выполняться параллельно только тогда, когда все подчиненные подзапросы являются параллельно-безопасными. Соответственно, принудительное параллельное выполнение любого из подзапросов позволяет выполнять параллельно UNION. Тем временем, подсказка о параллельном выполнении с нулевым количеством рабочих процессов препятствует выполнению сканирования параллельно.

F.40.6.6.4. Настройка параметров pg_hint_plan с помощью указаний Set

Параметры pg_hint_plan изменяют поведение самого себя, поэтому некоторые параметры не работают ожидаемым образом.

  • Подсказки для изменения enable_hint и enable_hint_tables игнорируются, даже если они отображаются как используемые подсказки в журналах отладки.

  • Установка debug_print и message_level работает из середины обработки целевого запроса.

F.40.7. Ошибки

pg_hint_plan прекращает разбор при возникновении ошибки и использует уже разобранные подсказки в большинстве случаев. Ниже приведены типичные ошибки.

F.40.7.1. Синтаксические ошибки

Любые синтаксические ошибки или неправильные имена подсказок сообщаются как синтаксическая ошибка. Эти ошибки сообщаются в журнале сервера с уровнем сообщения, указанным в pg_hint_plan.message_level, если pg_hint_plan.debug_print включен и выше.

F.40.7.2. Неправильные спецификации объекта

Неправильные спецификации объектов приводят к тихому игнорированию подсказок. Этот тип ошибки отображается в журнале сервера как неиспользуемые подсказки в той же самой ситуации, что и синтаксические ошибки.

F.40.7.3. Лишние или противоречивые подсказки

Последний подсказка будет активна, когда имеются избыточные подсказки или подсказки, конфликтующие друг с другом. Такого рода ошибка сообщается в журнале сервера как повторяющиеся подсказки при тех же условиях, что и синтаксические ошибки.

F.40.7.4. Вложенные комментарии

Подсказка комментария не может содержать другой блочный комментарий внутри. Если pg_hint_plan обнаруживает это, в отличие от других ошибок, он прекращает разбор и отказывается от всех уже разобранных подсказок. Этот тип ошибки сообщается таким же образом, как и другие ошибки.

F.40.8. Функциональные ограничения

F.40.8.1. Влияние некоторых параметров планировщика GUC

Планировщик не пытается учитывать порядок соединения для записей в FROM более чем from_collapse_limit. pg_hint_plan не может влиять на порядок соединения, как ожидалось в данном случае.

F.40.8.2. Подсказки, пытающиеся принудить выполнение невыполнимых планов

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

  • FULL OUTER JOIN для использования вложенного цикла

  • Для использования индексов, которые не имеют столбцов, используемых в quals

  • Для выполнения TID-сканирования для запросов без условий ctid

F.40.8.3. Запросы в ECPG

ECPG удаляет комментарии в запросах, написанных в виде встроенного SQL, поэтому невозможно передавать подсказки из этих запросов. Единственным исключением является команда EXECUTE, которая передает заданную строку без изменений. Пожалуйста, учтите таблицы подсказок в данном случае.

F.40.8.4. Работа с pg_stat_statements

pg_stat_statements генерирует идентификатор запроса, игнорируя комментарии. В результате, идентичные запросы с разными подсказками суммируются как один и тот же запрос.

F.40.9. Список подсказок

Доступные подсказки перечислены ниже.

Группа Формат Описание
Метод сканирования SeqScan(таблица) Принудительное последовательное сканирование таблицы
TidScan(table) Принудительно выполняет сканирование таблицы по TID.
IndexScan(table[ index...]) Принуждает к индексному сканированию таблицы. Ограничивает до указанных индексов, если таковые имеются.
IndexOnlyScan(table[ index...]) Принуждает к использованию только индексного сканирования таблицы. Ограничивает использование указанных индексов, если таковые имеются. Индексное сканирование может быть использовано, если сканирование только по индексу недоступно.
BitmapScan(table[ index...]) Принуждает выполнение сканирования таблицы по битовой карте. Ограничивает до указанных индексов, если таковые имеются.
IndexScanRegexp(table[ POSIX Regexp...]) IndexOnlyScanRegexp(table[ POSIX Regexp...]) BitmapScanRegexp(table[ POSIX Regexp...]) Принуждает к индексному сканированию или сканированию только по индексу или сканированию таблицы по битовой карте. Ограничивает индексы, которые соответствуют указанному шаблону регулярного выражения POSIX
NoSeqScan(table) Заставляет не выполнять последовательное сканирование таблицы.
NoTidScan(table) Принуждает не выполнять сканирование таблицы по TID.
NoIndexScan(table) Принуждает не выполнять индексное сканирование и сканирование только по индексу таблицы.
NoIndexOnlyScan(table) Принуждает не выполнять сканирование только по индексу таблицы.
NoBitmapScan(table) Принуждает не выполнять сканирование таблицы по битовой карте.
Метод соединения NestLoop(таблица таблица[ таблица...]) Принудительно использует вложенные циклы для соединений, состоящих из указанных таблиц.
HashJoin(table table[ table...]) Принудительно использует-соединение по хешу для соединений, состоящих из указанных таблиц.
MergeJoin(table table[ table...]) Принудительно использует соединение слиянием для соединений, состоящих из указанных таблиц.
NoNestLoop(table table[ table...]) Принуждает не выполнять вложенный цикл для соединений, состоящих из указанных таблиц.
NoHashJoin(table table[ table...]) Заставляет не выполнять соединение по хешу для соединений, состоящих из указанных таблиц.
NoMergeJoin(table table[ table...]) Запрещает выполнять соединение слиянием для соединений, состоящих из указанных таблиц.
Порядок соединения Leading(table table[ table...]) Принудительно задает указанный порядок соединения.
Leading(<join pair>) Принуждает к соблюдению указанного порядка и направлений соединения. Пара соединений - это пара таблиц и/или других пар соединений, заключенных в скобки, которые могут создать вложенную структуру.
Управление поведением при соединении Memoize(table table[ table...]) Разрешает самому верхнему соединению из соединений указанных таблиц мемоизовать внутренний результат. (Обратите внимание, что это не обязательное действие.)
NoMemoize(table table[ table...]) Запретить верхнему соединению из соединения среди указанных таблиц мемоизовать внутренний результат.
Коррекция номера строки Rows(table table[ table...] correction) Корректирует номер строки результата соединений, состоящих из указанных таблиц. Доступные методы коррекции - абсолютный (#), сложение (+), вычитание (-) и умножение (*). Должна быть строкой, которую strtod() может прочитать.
Конфигурация параллельного запроса Parallel(table # of workers [soft\|hard]) Принудительное выполнение или запрещение параллельной обработки указанной таблицы. # рабочих процессов- это желаемое количество параллельных рабочих процессов, где ноль означает запрещение параллельной обработки. Если третий параметр мягкий (по умолчанию), он просто меняет max_parallel_workers_per_gather и оставляет все остальное на усмотрение планировщика. Жесткий параметр означает принудительное использование указанного количества рабочих процессов.
GUC Set(GUC-param value) Установите параметр GUC на нужное начение во время работы планировщика.