Разделяемый кеш планов
ВНИМАНИЕ!
В релизе 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 | свободная память в байтах |