PREPARE
Подготавливает оператор к выполнению.
Синтаксис
PREPARE <name> [ ( <data_type> [, ...] ) ] AS <statement>
Описание
PREPARE создает подготовленный оператор. Подготовленный оператор — это объект на стороне сервера, который можно использовать для оптимизации производительности. При выполнении команды PREPARE указанный оператор анализируется, обрабатывается и переписывается. При последующем выполнении команды EXECUTE подготовленный оператор планируется и выполняется. Такое разделение обязанностей позволяет избежать повторяющейся работы по анализу и разбору, при этом план выполнения может зависеть от конкретных значений параметров.
Подготовленные операторы могут принимать параметры: значения, которые подставляются в оператор при его выполнении. При создании подготовленного оператора к этим параметрам можно обращаться по порядковому номеру, используя запись $1, $2 и т.д. Дополнительно можно указать список соответствующих типов данных параметров. Если тип данных параметра не указан или объявлен как unknown, тип определяется из контекста при первом обращении к этому параметру (если это возможно). При выполнении оператора фактические значения параметров передаются в команду EXECUTE.
Подготовленные операторы действуют только в течение текущей сессии работы с базой данных. После завершения сессии подготовленный оператор удаляется, поэтому его необходимо создать заново перед повторным использованием. Это также означает, что один подготовленный оператор не может использоваться несколькими одновременно работающими клиентами базы данных; однако каждый клиент может создать свой собственный подготовленный оператор. Подготовленные операторы можно удалить вручную с помощью команды DEALLOCATE.
Подготовленные операторы обеспечивают наибольшее преимущество в производительности, когда в рамках одной сессии выполняется большое количество однотипных операторов. Разница в производительности будет особенно существенной, если операторы сложны для планирования или перезаписи, например, если запрос включает объединение множества таблиц или требует применения нескольких правил. Если же оператор относительно прост для планирования и перезаписи, но относительно сложен для выполнения, преимущество подготовленных операторов в производительности будет менее заметным.
Параметры
| Параметр | Описание |
|---|---|
name |
Произвольное имя, назначаемое подготовленному оператору. Оно должно быть уникальным в рамках одной сессии и затем будет использоваться для выполнения или удаления ранее подготовленного оператора |
data_type |
Тип данных параметра подготовленного оператора. Если тип данных конкретного параметра не указан или указан как |
statement |
Оператор |
Примечания
Подготовленный оператор может выполняться с использованием либо общего плана, либо специализированного плана. Общий план одинаков для всех выполнений, тогда как специализированный план строится для конкретного выполнения с учетом значений параметров, указанных в данном вызове. Использование общего плана снижает издержки планирования, но в некоторых ситуациях специализированный план будет гораздо эффективнее, так как планировщик может использовать информацию о значениях параметров. Если подготовленный оператор не имеет параметров, всегда используется общий план.
По умолчанию (то есть когда параметр конфигурации сервера plan_cache_mode имеет значение auto) сервер автоматически выбирает, использовать ли общий или специализированный план для подготовленного оператора с параметрами. На данный момент действует следующее правило: первые пять выполнений осуществляются с использованием специализированных планов, и рассчитывается средняя стоимость этих планов. Затем строится общий план, и его примерная стоимость сравнивается со средней стоимостью специализированных планов. При последующих выполнениях будет использоваться общий план, если его стоимость не настолько выше средней стоимости специализированных планов, чтобы повторное перепланирование было предпочтительно.
Этот эвристический алгоритм можно переопределить, чтобы сервер выбирал только общие или только специализированные планы, установив для параметра plan_cache_mode значение force_generic_plan или force_custom_plan соответственно. Эта настройка в первую очередь полезна, если оценка стоимости общего плана по какой-либо причине сильно отличается от фактической, и он выбирается даже если его фактическая стоимость значительно выше, чем у специализированного плана.
Чтобы просмотреть план запроса, используемый Greengage DB для подготовленного оператора, используйте команду EXPLAIN, например:
EXPLAIN EXECUTE <name>(<parameter_values>);
Если применяется общий план, он будет содержать символы параметров $n, тогда как в специализированном плане будут подставлены фактические значения параметров.
Более подробную информацию о планировании запросов и статистике, собираемой Greengage DB для этих целей, можно найти в документации ANALYZE.
Хотя основная цель подготовленного запроса состоит в том, чтобы избежать повторного анализа и планирования оператора, Greengage DB будет принудительно повторно анализировать и планировать выполнение оператора перед его использованием всякий раз, когда объекты базы данных, задействованные в операторе, подвергаются изменениям определения (DDL) с момента предыдущего использования подготовленного оператора. Кроме того, если значение search_path меняется от одного использования оператора к другому, оператор будет повторно проанализирован с использованием нового search_path. Эти правила делают использование подготовленного оператора семантически почти эквивалентным многократной отправке одного и того же текста запроса, но с повышением производительности (если определения объектов не меняются), особенно если оптимальный план остается неизменным при каждом использовании. Пример ситуации, когда различия все же могут проявиться — когда оператор обращается к таблице по неполному имени, а затем в схеме, расположенной ранее в search_path, создается новая таблица с тем же именем. В этом случае автоматический повторный анализ не произойдет, поскольку ни один объект, используемый в операторе, не изменился. Однако, если в результате других изменений будет выполнен повторный анализ, при последующем выполнении запроса будет задействована новая таблица.
Все доступные в сессии подготовленные операторы можно просмотреть, обратившись к системному представлению pg_prepared_statements.
Примеры
Создание подготовленного оператора для команды INSERT и его последующее выполнение:
PREPARE fooplan (int, text, bool, numeric) AS INSERT INTO foo
VALUES ($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
Создание подготовленного оператора для команды SELECT и его последующее выполнение. Обратите внимание, что тип данных второго параметра не указан, поэтому он определяется из контекста, в котором используется $2:
PREPARE usrrptplan (int) AS SELECT *
FROM users u,
logs l
WHERE u.usrid = $1
AND u.usrid = l.usrid
AND l.date = $2;
EXECUTE usrrptplan(1, current_date);
Совместимость
Стандарт SQL включает оператор PREPARE, но он предназначен только для применения во встраиваемом SQL, и использует несколько иной синтаксис.