75.1. Как это работает #
Если во время выполнения запроса сработал триггер перепланирования, начнётся перепланирование этого запроса. Частично выполненный запрос игнорируется, и предпринимается попытка собрать информацию для дальнейшего перепланирования. Если полезная информация не найдена, выполнение запроса начинается сначала, но без активированных триггеров перепланирования. Информация об операторе запроса и оценке количества строк узлов сохраняется. Информация об узлах сохраняется для:
Непараметризованных узлов
Параметризованных узлов, фактическая мощность которых больше используемой планировщиком
Перепланирование продолжается до тех пор, пока не выполнено условие триггера или не превышено настроенное максимальное количество попыток перепланирования, либо пока находится новая информация. Максимальное количество попыток перепланирования определяется параметром конфигурации replan_max_attempts.
Если триггер перепланирования активирован, запрос, соответствующий условию триггера, выполняется в неявно созданной подтранзакции. В случае перепланирования это помогает выполнять очистку после предыдущего запроса и освобождать системные ресурсы, такие как память или дисковое пространство.
75.1.1. Триггеры перепланирования #
Следующие триггеры могут прервать запрос и запустить перепланирование:
Время выполнения запроса: триггер срабатывает, если запрос выполняется дольше, чем указано в параметре конфигурации replan_query_execution_time.
Количество обработанных кортежей узлов: триггер срабатывает, когда количество таких кортежей превышает число, обычно ожидаемое планировщиком, которое умножается на значение параметра конфигурации replan_overrun_limit.
Потребление памяти рабочим процессом: триггер срабатывает, когда потребление памяти рабочим процессом превышает значение параметра конфигурации replan_memory_limit и срабатывает триггер количества обработанных кортежей узлов.
75.1.2. Просмотр подробностей о перепланировании #
Если параметр replan_show_signature включён, информация, связанная с перепланированием, добавляется в вывод команды EXPLAIN ANALYZE
. Раздел SUMMARY
дополнительно включает следующие характеристики:
Replan Active
— срабатывал ли триггер перепланирования во время выполнения запроса.Table Entries
— количество таблиц в запросе, включая подзапросы.Controlled Statements
— количество операторов, которые были перепланированы во время выполнения запроса.Replanning Attempts
— общее количество перезапусков/попыток перепланирования запроса.Total Execution Time
— общее время выполнения запроса, включая время всех попыток перезапуска/перепланирования.
Для каждого узла плана включены следующие характеристики:
NodeSign
— 64-битная подпись (хеш) узла, которая однозначно идентифицирует узел плана запроса. Подписаны не все узлы, а только те, где ошибки модели оценки оптимизатора могут приводить к ошибкам в поиске оптимального плана запроса.Cardinality
— количество кортежей узла плана, достигнутое при предыдущих выполнениях запроса. Доступно только с параметромVERBOSE
.Groups Number
— количество групп, вычисленное для этого узла плана в результате предыдущих выполнений запроса. Доступно только с параметромVERBOSE
.
75.1.3. Пример #
Пример 75.1. Использование перепланирования
В следующем примере показано использование перепланирования:
SET replan_show_signature = 'on'; SET replan_query_execution_time = 10; SET replan_enable = 'on'; DROP TABLE IF EXISTS replan_test CASCADE; CREATE TABLE replan_test WITH (autovacuum_enabled = off) AS SELECT 1 AS x, 'abc' AS payload FROM generate_series(1,1E4); ANALYZE replan_test; INSERT INTO replan_test (x,payload) ( SELECT gs, repeat('a', 256) FROM generate_series(1,100) AS gs); EXPLAIN ANALYZE VERBOSE SELECT count(*) FROM ( SELECT q2.x,q2.payload, max(q2.x) FROM ( SELECT rt1.x, rt1.payload FROM replan_test rt1 ) AS q2 GROUP BY (q2.x,q2.payload) HAVING avg(q2.x) > 30 ) AS q1, replan_test rt2 WHERE q1.x=rt2.x ;
Результат:
Aggregate (cost=560.06..560.07 rows=1 width=8) (actual time=4.705..4.707 rows=1 loops=1) NodeSign: 4127104911444856927 Cardinality: -1 Groups Number: -1 Output: count(*) -> Hash Join (cost=232.05..533.39 rows=10667 width=0) (actual time=4.681..4.701 rows=70 loops=1) NodeSign: 15478158356720060206 Cardinality: -1 Groups Number: -1 Hash Cond: (rt2.x = q1.x) -> Seq Scan on public.replan_test rt2 (cost=0.00..154.67 rows=10667 width=4) (actual time=0.007..0.785 rows=10100 loops=1) NodeSign: 17491169463296369090 Cardinality: -1 Groups Number: -1 Output: rt2.x, rt2.payload -> Hash (cost=231.99..231.99 rows=5 width=4) (actual time=3.083..3.084 rows=70 loops=1) NodeSign: 17790666881744499777 Output: q1.x Buckets: 1024 Batches: 1 Memory Usage: 11kB -> Subquery Scan on q1 (cost=230.42..231.99 rows=5 width=4) (actual time=3.026..3.073 rows=70 loops=1) NodeSign: 17790666881744499777 Output: q1.x -> HashAggregate (cost=230.42..231.94 rows=5 width=12) (actual time=3.025..3.065 rows=70 loops=1) NodeSign: 13744336777062894583 Cardinality: 5 Groups Number: 101 Output: rt1.x, rt1.payload, NULL::integer Group Key: rt1.x, rt1.payload Filter: (avg(rt1.x) > '30'::numeric) Batches: 1 Memory Usage: 80kB Rows Removed by Filter: 31 -> Seq Scan on public.replan_test rt1 (cost=0.00..154.67 rows=10100 width=8) (actual time=0.004..0.865 rows=10100 loops=1) NodeSign: 14925644762129093451 Cardinality: 10100 Groups Number: -1 Output: rt1.x, rt1.payload Planning Time: 0.135 ms Execution Time: 4.746 ms Replan Active: true Table Entries: 2 Controlled Statements: 1 Replanning Attempts: 1 Total Execution Time: 15.530 ms