Содержание

Предыдущий раздел

Различия в работе volatile и stable функций

Следующий раздел

Ошибки при работе с рекомендательными (advisory) блокировками

Кеширование результата запроса в PL/pgSQL функции

В больших, объемных pl-процедурах бывают ситуации, когда по каким-либо причинам в нескольких местах приходится использовать одни и те же запросы и обрабатывать их результаты. Что-то похожее на двухпроходные алгоритмы - обработали данные, накопили результаты, повторно обработали те же данные - получили конечный результат. Если запросы выполняются быстро, то проблем нет, но ситуации бывают разные, и иногда хочется как-то сохранить результат выполнения запроса и использовать сохраненный результат в дальнейшем. Для хранения кода может отлично подойти массив записей. К примеру, имеется таблица customers

CREATE TABLE customers (
    id int PRIMARY KEY,
    name varchar NOT NULL UNUQUE
);

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

SELECT * FROM customers WHERE name ILIKE '%z%';

Для кеширования можно использовать следующий подход:

DECLARE
  _customers customers[]; -- В этом массиве будет хранится результат выполнения запроса
  _customer customers;
BEGIN
  -- Функцию ARRAY удобно использовать, так как, если запрос не вернет ни одной строки, то результатом будет пустой
  -- массив, а не значение NULL, если бы использовалась функция array_agg
  _customers := ARRAY(SELECT c FROM customers AS c WHERE name ILIKE '%z%'); -- Закешировали результат запроса

  FOR _customer IN SELECT * FROM unnest(_customers) -- Простое использование закешированного результата
  LOOP
  END LOOP;

  FOR _customer IN SELECT * FROM unnest(_customers) WHERE id > 100 -- Закешированный результат можно дополнительно отфильтровать
  LOOP
  END LOOP;
END

Вот так всё просто.

Примечание

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

Дополнительная информация

PostgreSQL Documentation: Array Functions and Operators

comments powered by Disqus