Разделяемый кеш планов

ВНИМАНИЕ!
В релизе QHB 1.5.3 этот функционал является экспериментальным, его использование в установке на производственной среде не рекомендовано.

Разделяемый кеш планов позволяет экономить процессорное время, не пересоздавая планы выполнения SQL-запросов, сохраняя их в разделяемой памяти. Это является отличительной особенностью по сравнению с кешем планов в обычном PostgreSQL.



Параметры разделяемого кеша в qhb.conf

qhb_plan_cache_size – размер буфера разделяемой памяти. При нулевом значении кеш отключен.

compute_query_id – включает встроенное вычисление ID запросов. Значение должно быть on или auto либо не задано, что равносильно auto. При значении off кеш отключен.

Пример настройки:

qhb_plan_cache_size = 100MB # включает кеш планов с буфером в 100 МБ
compute_query_id = auto


Ограничения

В кеш попадают только общие планы, не зависящие от параметров (см. plan_cache_mode).

Общий план формируется в следующих случаях:

  • задан параметр plan_cache_mode = force_generic_plan. Его можно задать в файле qhb.conf и в параметрах сеанса командой SET plan_cache_mode TO force_generic_plan;
  • в функцию SPI_prepare_cursor передан CURSOR_OPT_GENERIC_PLAN
  • в тексте запроса при вызове функции SPI_prepare или в команде PREPARE записаны параметры ($1, $2 и т. д.) вместо значений
  • после 6 запусков одного и того же запроса с разными параметрами формируется общий план. QHB его использует, если стоимость общего плана меньше среднего значения стоимости частных планов.

Обязательное условие: использование PREPARE, SPI_prepare или расширенного протокола обмена между клиентом и сервером (PARSE-BIND-EXECUTE). В противном случае запрос считается одноразовым, плану выставляется соответствующий признак, и формирование общего плана не выполняется.



Представления

Представления позволяют посмотреть информацию о содержимом кеша.

qhb_sql_cache_info

Представление qhb_sql_cache_info содержит статистику по кешу целиком.

Столбец ТипОписание
total_cache_size int8размер кеша в байтах (из настроек)
free_cache_size int8свободное место в байтах
count int4количество сохраненных планов
total_plan_size int8занятая память в байтах
min_plan_size int4минимальный размер плана в байтах
max_plan_size int4максимальный размер плана в байтах
mean_plan_size int4средний размер плана в байтах

qhb_sql_plans_info

Представление qhb_sql_plans_info содержит список сохраненных планов и статистику по каждому плану.

Столбец ТипОписание
queryid int8Идентификатор запроса, сгенерированный ядром (этот же идентификатор используется в расширениях pg_store_plans, pg_stat_statements, sr_plan)
query textтекст запроса
size int4размер плана в памяти
plan_time int8время планирования в наносекундах
cost float8стоимость выполнения
reads int8количество чтений плана из кеша
references int4количество ссылок на план (количество бэкендов)
executes int8количество выполнений плана
total_exec_time int8общее время выполнения в наносекундах
min_exec_time int8минимальное время выполнения в наносекундах
max_exec_time int8максимальное время выполнения в наносекундах
mean_exec_time int8среднее время выполнения в наносекундах

Так как queryid в qhb_sql_plans_info совпадает с queryid в представлениях pg_store_plans, pg_stat_statements и таблице sr_captured_queries, то их можно связывать в запросах, если соответствующие расширения включены.



Отображение плана запроса

Для отображения плана сохраненного запроса можно использовать команду:

EXPLAIN CACHED_PLAN [ ( параметр [, ...] ) ] queryid
EXPLAIN CACHED_PLAN [ ANALYZE ] [ VERBOSE ] queryid

Синтаксис идентичен обычной команде EXPLAIN, только нужно добавить CACHED_PLAN и вместо запроса указать queryid из представления qhb_sql_plans_info.



Метрики

ИмяОписание
qhb.shared_cache.invokesколичество обращений к кешу
qhb.shared_cache.plannedколичество планирований
qhb.shared_cache.foundколичество попаданий в кеш, то есть сколько раз запрошенный план был найден
qhb.shared_cache.lenколичество хранимых планов
qhb.shared_cache.shmem_freeсвободная память в байтах