pg_outline. Изменение плана выполнения запросов#
Версия: 1.1.
В исходном дистрибутиве установлено по умолчанию: да.
Связанные компоненты: отсутствуют.
Схема размещения:
outline.
Расширение pg_outline предназначено для изменение плана выполнения запросов.
Функциональные возможности расширения pg_outline#
Функциональные возможности:
управление (добавить, заменить, удалить, включить, выключить) правилами подмены (фиксациями подсказок
pg_hint_plan) планов запросов;возврат информации о созданных правилах подмены планов запросов;
возврат идентификатора запроса (
queryId) для текста запроса (queryText).
Подробное описание в документе «Список PL/SQL функций продукта» раздел «Функциональные возможности расширения pg_outline» (доступен в личном кабинете).
Подмена подсказок#
Получение идентификатора запроса (query ID)#
Идентификатор запроса используется для сопоставления выполняемого запроса и правила фиксации и/или подмены этого запроса.
Получить идентификатор в ручном режиме можно через:
расширение
pg_stat_statements;функцию
outline.identify. Подробнее в документе «Список PL/SQL функций продукта», раздел «Функциональные возможности расширенияpg_outline» (документ доступен в личном кабинете).
Получение идентификатора при помощи расширения pg_stat_statements#
Для получения идентификатора при помощи расширения pg_stat_statements выполните:
Если запрос, для которого нужно узнать идентификатор, выполняется впервые, сначала выполните любой простой запрос, например:
SELECT * FROM table1;Найдите идентификатор запроса (поле
queryid) в таблице расширенияpg_stat_statements:SELECT * FROM pg_stat_statements;Примечание:
Идентификатор запроса (поле
queryid) представляет собой целое положительное или отрицательное число.
Получение идентификатора при помощи функции outline.identify#
Для получения идентификатора передайте текст запроса в качестве аргумента:
SELECT outline.identify( 'SELECT * FROM mytable WHERE x=10;' );
Примечание:
В тексте запроса (
queryText) обязательно укажите все константы. Это необходимо для определения типа данных этих констант (само значение констант неважно).
Особенности#
В данном разделе приведены особенности работы с расширением pg_outline.
Номера ссылок#
Не допускается указывать номер ссылки больший, чем количество констант в исходном запросе. В остальном на количество и порядок следования ссылок в подменяющем запросе ограничений нет.
Формирование идентификатора#
В зависимости от метода передачи параметров некоторые запросы могут иметь разный идентификатор (queryid). Например, два идентичных (в генерализованном виде) запроса будут иметь разные query_id:
PREPARE foo1(int) AS SELECT f1, f2 FROM table1 where f1 = $1
PREPARE foo2 AS SELECT f1, f2 FROM table1 where f1 = 123
Доработка#
Доработка: Фиксация планов запросов.
Версия: 4.5.0.
Ограничения#
Ограничения отсутствуют.
Установка#
Установка расширения может быть произведена в процессе развертывании СУБД Pangolin при использовании настроек по умолчанию (документ «Руководство по установке», раздел «Автоматизированная установка при помощи Ansible-скриптов»).
По умолчанию расширение загружается, но выключено. Все функции расширения недоступны и подмен не производится.
Для включения расширения необходимо установить конфигурационный параметр pg_outline.enable в значение true.
Включить расширение pg_outline можно:
только для текущей сессии:
SET pg_outline.enable = TRUE;для всех сессий — в
postgresql.confпропишите:pg_outline.enable = on
Примечание:
Начиная с версии Pangolin 6.4.3
pg_outlineподдерживает мажорные обновления. Во время таких обновлений идентификатор запроса (queryId) обычно изменяется, что делает старые значения внутри таблицыoutlinesнедействительными. Для решения этой проблемы была добавлена отдельная таблицаoutline_ref, в которой хранится связь междуqueryIdиquery_text. После мажорных обновлений, используя этотquery_text, пересчитываетсяqueryId, делаяoutlinesснова действительными.Обратите внимание, что данные добавляются в таблицу
outline_refпри выполнении операцийsetилиset_hint, когда предоставляетсяquery_text. Поэтому использование функции сqueryIdвместоquery_text, после мажорного обновления приведет к появлению недействительных обрисовок.
Настройка#
Перед использованием расширения pg_outline рекомендуется настроить защиту от изменения таблицы outline.outlines и триггера предотвращения изменения таблицы (pg_outline_prevent_table_modification). Для этого нужно поместить таблицу outline.outlines под защиту при включенной защите от привилегированных пользователей.
Использование модуля#
Порядок вывода функции outline.get#
Рассматривается пример заведение нового hint и проверка вывода информации об этом hint функциями outline.get(text) и outline.get(bigint).
Шаги
Создайте hint для запроса, выполнив команду:
SELECT outline.set_hint( 'SELECT f1, f2 FROM table2 WHERE f1 < 250 ORDER BY f1 LIMIT 1;', 'SeqScan(table2)' );Проверьте вывод функции
outline.get(text), выполнив команду:SELECT * FROM outline.get( 'SELECT f1, f2 FROM table2 WHERE f1 < 250 ORDER BY f1 LIMIT 1;' );Пример вывода:
| queryid | plan | outline | applicationname | active | |---------------------|---------------------------------|------------------------|-----------------|--------| | <queryid> | Limit +| /*+ SeqScan(table2) */ | | t | | | -> Sort +| | | | | | Sort Key: f1 +| | | | | | -> Seq Scan on table2 +| | | | | | Filter: (f1 < $1)+| | | | | | | | | |Проверьте вывод функции
outline.get(bigint), выполнив команду:SELECT * FROM outline.get( <queryid> );Идентификатор подставьте из предыдущего пункта. Пример вывода:
| queryid | plan | outline | applicationname | active | |---------------------|---------------------------------|------------------------|-----------------|--------| | <queryid> | Limit +| /*+ SeqScan(table2) */ | | t | | | -> Sort +| | | | | | Sort Key: f1 +| | | | | | -> Seq Scan on table2 +| | | | | | Filter: (f1 < $1)+| | | | | | | | | |
Работа подготавливаемых запросов с подзапросами при активном расширении pg_outline#
Шаги:
Включите
pg_outline(если не включен):CREATE EXTENSION IF NOT EXISTS pg_outline; CREATE EXTENSION IF NOT EXISTS pg_hint_plan; ALTER SYSTEM SET pg_hint_plan.enable_hint TO on; ALTER SYSTEM SET pg_outline.enable TO on; SELECT pg_reload_conf();Проверьте работу подмены плана запроса, выполнив запрос:
CREATE TABLE t( id INTEGER, PRIMARY KEY (id) ); INSERT INTO t(id) SELECT generate_series(1,1000); PREPARE plane4(int) AS DELETE FROM t WHERE id IN (select 1); SELECT outline.set_hint('DELETE FROM t WHERE id IN (select 1);', 'SeqScan(t)'); EXPLAIN EXECUTE plane4(4); SELECT outline.delete('DELETE FROM t WHERE id IN (select 1);'); DROP TABLE t;В выведенном плане запроса должна использоваться схема последовательного сканирования таблицы (
Seq Scan):QUERY PLAN -------------------------------------------------------- Delete on t (cost=0.00..41.88 rows=1 width=6) -> Seq Scan on t (cost=0.00..41.88 rows=1 width=6) Filter: (id = $1) (3 rows)
Пересчет идентификатора запроса#
Расширение включает функцию outline.recompute_query_ids, которая позволяет использовать текст запроса в таблице outline_ref для пересчета идентификатора запроса в таблице outlines.
При пересоздании таблиц меняется oid таблицы, что приводит к изменению идентификатора запроса, и неработоспособности старых правил подмены и подсказок. Для решения этой проблемы была добавлена функция outline.recompute_query_ids, которая пересчитывает идентификатор запроса, используя текст запроса. Это позволяет присоединить существующие правила к запросам на новых таблицах.
Примечание: Вызов функции
outline.recompute_query_idsприводит к инвалидации всех правил подмены и подсказок, которые были созданы до вызова этой функции.