G.6. pgpro_result_cache — сохранение результатов запросов для переиспользования #

G.6.1. Описание #

Расширение pgpro_result_cache кеширует результаты запросов в разделяемой памяти с помощью указаний, повышая производительность при повторном выполнении запросов. Кешированные результаты не сохраняются после перезапуска сервера.

G.6.2. Установка #

Расширение pgpro_result_cache поставляется вместе с Postgres Pro Enterprise в виде отдельного пакета pgpro-result-cache-ent-17 (подробные инструкции по установке приведены в Главе 17).

Чтобы включить pgpro_result_cache, выполните следующие действия:

  1. Добавьте имя библиотеки в переменную shared_preload_libraries в файле postgresql.conf:

    shared_preload_libraries = 'pgpro_result_cache'
  2. Перезагрузите сервер баз данных, чтобы изменения вступили в силу.

    Чтобы убедиться, что библиотека pgpro_result_cache установлена правильно, выполните следующую команду:

    SHOW shared_preload_libraries;
  3. Создайте расширение pgpro_result_cache с помощью следующего запроса:

    CREATE EXTENSION pgpro_result_cache;

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

  4. Включите расширение с помощью параметра pgpro_result_cache.enable.

    SET pgpro_result_cache.enable = ON;

G.6.3. Использование указаний #

Задавайте любые поддерживаемые указания в комментарии особого вида, который начинается с символов /*+ и заканчивается символами */. Учтите, что pgpro_result_cache читает только первый блок комментариев. Если задано несколько указаний, применяется только последнее.

G.6.3.1. Использование указания result_cache #

Используйте указание result_cache, чтобы pgpro_result_cache обработал запрос.

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

-- Кеширует текущее время
SELECT /*+result_cache*/ now();

-- Возвращает ранее сохранённое время из кеша
SELECT /*+result_cache*/ now();

Указание result_cache имеет два необязательных аргумента со следующими ключевыми словами:

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

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

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

Эти аргументы похожи на предложения OFFSET и LIMIT, которые используются в запросах, но применяются к кешированным наборам результатов, а не к строкам, полученным с помощью запросов. Эти запросы, в свою очередь, могут иметь свои предложения OFFSET и LIMIT.

CREATE TABLE t as SELECT generate_series(1,20) x;

-- Кеширует значения от 1 до 20, возвращает значения от 1 до 10
SELECT /*+result_cache(limit 10)*/ x FROM t;

-- Возвращает значения от 6 до 20
SELECT /*+result_cache(offset 5)*/ x FROM t;

-- Оба запроса возвращают значения от 6 до 15
SELECT /*+result_cache(offset 5 limit 10)*/ x FROM t;
SELECT /*+result_cache(limit 10 offset 5)*/ x FROM t;

-- Кеширует значения от 6 до 20, возвращает значения от 11 до 20
SELECT /*+result_cache(offset 5 limit 10)*/ x FROM t OFFSET 5;

-- Кеширует значения от 1 до 10, возвращает значения от 6 до 10
SELECT /*+result_cache(offset 5 limit 10)*/ x FROM t LIMIT 10;

G.6.3.2. Использование указания no_result_cache #

Используйте указание no_result_cache, чтобы pgpro_result_cache не обрабатывал запрос, то есть не кешировал результаты запроса и не использовал существующие кешированные результаты.

Например, это указание полезно, когда для параметра pgpro_result_cache.enforced установлено значение on в целях отладки для автоматического кеширования всех запросов. Это указание позволяет исключить отдельные запросы из кеширования.

SET pgpro_result_cache.enforced = on;

-- Кеширует текущее время
SELECT now();

-- Возвращает ранее сохранённое время из кеша
SELECT now();

-- Возвращает текущее время
SELECT /*+no_result_cache*/ now();

G.6.4. Кеширование и хранение наборов результатов #

Все кешированные наборы результатов хранятся в разделяемой памяти. Можно получить информацию об этих наборах результатов с помощью представления pgpro_result_cache_data.

Параметр pgpro_result_cache.max_memory_size задаёт максимальный размер разделяемой памяти кеша. Параметр pgpro_result_cache.max_entries определяет максимальное количество кешированных наборов результатов. Если при добавлении нового значения достигнут какой-то из этих пределов, pgpro_result_cache удаляет наборы результатов из памяти кеша с помощью алгоритма вытеснения давно неиспользуемых данных (least recently used, LRU).

Можно также указать время жизни (Time To Live, TTL) кешированных наборов результатов с помощью параметра pgpro_result_cache.ttl. Набор результатов считается действительным и хранится в памяти кеша пока не истечёт его TTL.

По умолчанию автоматическое аннулирование кеша выключено. Учитывайте следующие особенности работы расширения:

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

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

Примечание

Кешированные результаты игнорируют политику защиты на уровне строк. Убедитесь, что конфиденциальные запросы не кешируются.

G.6.5. Идентификация кешированного набора результатов #

Кешированный набор результатов идентифицируется комбинацией атрибутов database_id, query_id, const_hash, params_hash и query_string. Атрибуты database_id и query_id назначаются сервером Postgres Pro Enterprise.

const_hash содержит вычисленный хеш всех констант, содержащихся в запросе. Константы с одинаковым значением, но разными типами, например, 1 и '1', дадут разные значения хеша. 0 означает отсутствие констант.

params_hash содержит вычисленный хеш всех значений параметров запроса. 0 означает отсутствие параметров.

G.6.6. Автоматическое аннулирование #

Расширение pgpro_result_cache поддерживает автоматическое аннулирование для обеспечения согласованности кешированных результатов с помощью отслеживания изменений базы данных и применения определённых ограничений. По умолчанию автоматическое аннулирование выключено. Чтобы включить его, установите для параметра pgpro_result_cache.consistent значение on. Изменение этого параметра сбрасывает кеш.

Когда включено автоматическое аннулирование, расширение работает следующим образом:

  • Кеширует только запросы, которые не вносят изменения в базу данных. Не обслуживает транзакции (ни читающие, ни пишущие), которые имеют незафиксированные изменения.

  • При каждой DML-операции, например, INSERT, UPDATE, DELETE или TRUNCATE, аннулирует кешированные результаты, связанные с изменёнными отношениями.

  • При каждой DDL-операции, например, ALTER TABLE или DROP TABLE, аннулирует кешированные результаты, связанные с изменёнными отношениями.

  • Не кеширует запросы, использующие временные таблицы.

  • Не кеширует запросы, использующие нежурналируемые таблицы.

  • Не кеширует запросы, использующие пользовательские функции или типы.

  • Не кеширует запросы, использующие изменяемые функции.

Чтобы включить автоматическое аннулирование на уровне кластера, установите для параметров pgpro_result_cache.consistent и pgpro_result_cache.wal значения on на ведущем узле и всех ведомых узлах. В этом случае ведущий узел и каждый ведомый узел хранят свои собственные кешированные наборы результатов. Каждая DML- или DDL-операция на ведущем узле вызывает автоматическое аннулирование кеша для соответствующих отношений на всех ведомых узлах с помощью файлов WAL.

Примечание

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

G.6.7. Совместимость с pg_hint_plan #

Указания расширения pgpro_result_cache можно использовать вместе с указаниями, поддерживаемыми расширением pg_hint_plan. Каждое расширение читает только его поддерживаемые указания и игнорирует остальные.

/*+result_cache SeqScan(t1)*/
SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key);

G.6.8. Представления #

G.6.8.1. Представление pgpro_result_cache_data #

Представление pgpro_result_cache_data отображает все кешированные наборы результатов. Столбцы представления показаны в Таблице G.84.

Таблица G.84. Столбцы pgpro_result_cache_data

ИмяТипОписание
dbidoidИдентификатор базы данных, в которой выполнялся запрос
query_idbigintСтандартный идентификатор запроса
const_hashbigintХеш непараметризованных констант
params_hashbigintХеш параметров запроса
createdtimestampВременная метка первого кеширования
exec_time_msrealВремя выполнения запроса, в миллисекундах
hitsintКоличество выполнений
rows_countintЧисло строк в кешированном наборе результатов
data_sizebigintОбщий размер набора результатов в памяти кеша, в байтах
query_stringtextТекст запроса в формате, пригодном для кеширования, без комментариев или префиксов EXPLAIN (ANALYZE)

G.6.8.2. Представление pgpro_result_cache_stat #

Представление pgpro_result_cache_stat отображает счётчики кеша. Столбцы представления показаны в Таблице G.85.

Таблица G.85. Столбцы pgpro_result_cache_stat

ИмяТипОписание
free_kbbigintДоступная память кеша, в килобайтах, ограниченная pgpro_result_cache.max_memory_size
entriesbigintТекущее число записей в кеше, включая устаревшие (если они не были удалены), ограниченное pgpro_result_cache.max_entries
hitsbigintЧисло успешных извлечений из кеша
insertsbigintЧисло новых записей, включая замены устаревших
evictsbigintЗаписи, удалённые с помощью алгоритма вытеснения давно неиспользуемых данных (LRU) при достижении предела pgpro_result_cache.max_entries
cleanupsbigintЗаписи, удалённые с помощью алгоритма вытеснения давно неиспользуемых данных (LRU) при достижении предела pgpro_result_cache.max_memory_size
not_cachedbigintЗапросы, исключённые из кеширования (из-за высокой скорости выполнения, большого размера или иных причин)

G.6.9. Функции #

Вызывать нижеуказанные функции может только суперпользователь.

pgpro_result_cache_reset() returns bool #

Очищает кеш и сбрасывает все счётчики кешированных результатов. Возвращает true, если кешированные наборы результатов были удалены, и false, если кеш был пуст.

G.6.10. Параметры конфигурации #

pgpro_result_cache.enable (boolean) #

Активирует функциональность расширения pgpro_result_cache. Значение по умолчанию — off. Изменить этот параметр могут только суперпользователи.

pgpro_result_cache.max_memory_size (integer) #

Задаёт размер разделяемой памяти, используемой для кеширования наборов результатов, в килобайтах. Значение по умолчанию — 64kB. Этот параметр можно задать только в файле postgresql.conf или при помощи команды ALTER SYSTEM.

pgpro_result_cache.max_entries (integer) #

Устанавливает максимальное число кешированных наборов результатов. Значение по умолчанию — 128. Этот параметр можно задать только при запуске сервера.

pgpro_result_cache.max_entry_size (integer) #

Задаёт максимальный объём потребления памяти для одного набора результатов, в килобайтах. Значение по умолчанию — 16kB. Изменять этот параметр могут только суперпользователи. Не может превышать pgpro_result_cache.max_memory_size / 2. Текст запроса хранится в памяти вместе с данными результатов, поэтому значение параметра должно быть достаточно большим для размещения обоих значений. При изменении параметра во время выполнения он применяется только к новым кешируемым результатам без автоматического вытеснения существующих.

pgpro_result_cache.ttl (integer) #

Задаёт время жизни кешированного результата, в секундах. Значение по умолчанию — -1, что означает отсутствие ограничения времени жизни. Изменить этот параметр могут только суперпользователи.

pgpro_result_cache.min_exec_time (integer) #

Задаёт минимальное время выполнения запроса, в миллисекундах. Значение по умолчанию — -1, что означает отсутствие ограничения времени. Положительное целое число означает, что запросы, выполняющиеся быстрее указанного времени, не будут сохраняться в кеше. Изменять этот параметр могут только суперпользователи.

pgpro_result_cache.consistent (boolean) #

Включает автоматическое аннулирование кешированных результатов. Значение по умолчанию — off. Этот параметр можно задать только в файле postgresql.conf или при помощи команды ALTER SYSTEM. Изменение этого параметра сбрасывает кеш.

pgpro_result_cache.wal (boolean) #

Разрешает использование файлов WAL для автоматического аннулирования кеша на уровне кластера. Для корректной работы аннулирования необходимо установить для параметров pgpro_result_cache.consistent и pgpro_result_cache.wal значения on на ведущем узле и всех ведомых узлах. Значение по умолчанию параметра pgpro_result_cache.waloff. Этот параметр можно задать только в файле postgresql.conf или при помощи команды ALTER SYSTEM.

pgpro_result_cache.enforced (boolean) #

Позволяет pgpro_result_cache автоматически кешировать наборы результатов для всех запросов. Чтобы исключить определённые запросы из кеширования, можно использовать указание no_result_cache. Значение по умолчанию — off. Изменить этот параметр могут только суперпользователи. Изменение этого параметра сбрасывает кеш. Этот параметр предназначен для отладки, не рекомендуется использовать его в производственной среде.

pgpro_result_cache.invisible (boolean) #

Скрывает информацию о pgpro_result_cache из вывода EXPLAIN. Значение по умолчанию — off. Изменить этот параметр могут только суперпользователи. Изменение этого параметра сбрасывает кеш. Этот параметр предназначен для целей отладки и не рекомендован для использования в рабочей среде.