PREPARE — подготовка выражения к выполнению
PREPAREname[ (data_type[, ...] ) ] ASexpression
PREPARE создает подготавливаемое выражение. Подготавливаемое
выражение представляет собой объект на стороне сервера, который может использоваться для оптимизации
производительности. Когда PREPARE выполняется инструкция, указанное выражение проходит разбор, анализ и перезапись. Когда EXECUTE впоследствии подается команда, для подготавливаемого выражения строится план и оно выполняется. Такое разделение задач позволяет избежать повторения операций по разбору и анализу, при этом план выполнения может зависеть от конкретных предоставленных значений параметров.
Подготавливаемые выражения могут принимать параметры: значения, которые подставляются в выражение при его выполнении. При создании
подготавливаемого выражения обращение к параметрам осуществляется по их позиции с использованием
$1, $2, и т. д. Дополнительно может быть указан соответствующий список типов данных параметров. Если тип данных параметра не указан или объявлен как
unknown, тип выводится из контекста
первого упоминания параметра (если это возможно). При выполнении выражения следует указать фактические значения этих параметров в
EXECUTE выражении. См. EXECUTE для получения
дополнительной информации об этом.
Подготавливаемые выражения существуют только в течение текущего сеанса базы данных. При завершении сеанса подготавливаемое выражение
удаляется, поэтому перед повторным использованием его необходимо создать заново. Это также означает, что одно подготавливаемое выражение не может использоваться несколькими параллельными клиентами базы данных одновременно; тем не менее, каждый клиент может создать собственное подготавливаемое выражение. Подготавливаемые выражения можно удалить вручную с помощью команды DEALLOCATE command.
Подготавливаемые выражения потенциально обеспечивают наибольшее преимущество в производительности, когда один сеанс используется для выполнения большого количества однотипных выражений. Разница в производительности будет особенно значительной, если выражения сложны в планировании или переписывании, например, если запрос включает соединение многих таблиц или требует применения нескольких правил. Если выражение относительно просто в планировании и переписывании, но относительно затратно в выполнении, преимущество в производительности подготавливаемых выражений будет менее заметным.
nameПроизвольное имя, присваиваемое данному конкретному подготавливаемому выражению. Оно должно быть уникальным в рамках одного сеанса и в дальнейшем используется для выполнения или удаления ранее созданного подготавливаемого выражения.
data_type
Тип данных параметра подготавливаемого выражения. Если тип данных конкретного параметра не указан или указан как unknown, он будет определен на основе контекста, в котором этот параметр упоминается впервые. Для обращения к параметрам в самом подготавливаемом выражении используйте
$1, $2, и т. д.
expression
Любой SELECT, INSERT, UPDATE,
DELETE, MERGE, или VALUES
выражение.
Подготавливаемое выражение может быть выполнено либо с использованием общего плана или индивидуальный план. Общий план остается одинаковым для всех выполнений, в то время как индивидуальный план формируется для конкретного выполнения с использованием значений параметров, переданных в данном вызове. Использование общего плана позволяет избежать накладных расходов на планирование, но в некоторых ситуациях индивидуальный план оказывается гораздо эффективнее, так как планировщик может использовать информацию о значениях параметров. (Разумеется, если подготавливаемое выражение не имеет параметров, этот вопрос не возникает и всегда используется общий план.)
По умолчанию (то есть когда значение plan_cache_mode установлено
в auto), сервер автоматически выбирает, использовать ли общий или индивидуальный план для подготавливаемого выражения с параметрами. Текущее правило заключается в том, что первые пять выполнений производятся с использованием индивидуальных планов, для которых рассчитывается средняя оценочная стоимость. Затем создается общий план, и его оценочная стоимость сравнивается со средней стоимостью индивидуальных планов. Последующие выполнения используют общий план, если его стоимость не настолько превышает среднюю стоимость индивидуальных планов, чтобы повторное планирование считалось предпочтительным.
Эту эвристику можно переопределить, принудительно заставив сервер использовать либо общие планы, либо индивидуальные планы путем установки plan_cache_mode
в значение force_generic_plan
или force_custom_plan соответственно. Данная настройка полезна прежде всего в тех случаях, когда оценка стоимости общего плана по какой-то причине оказывается сильно неверной, что позволяет выбрать его, даже если его фактическая стоимость значительно превышает стоимость индивидуального плана.
Для изучения плана запроса, Digital Q.DataBase используемого
для подготавливаемого выражения, следует использовать команду EXPLAIN, например
EXPLAIN EXECUTEимя(parameter_values);
Если используется общий план, он будет содержать обозначения параметров
$, тогда как в индивидуальный план будут подставлены фактические значения предоставленных параметров.
n
Для получения дополнительных сведений о планировании запросов и статистике, собираемой Digital Q.DataBase для этих целей, см. раздел ANALYZE документации.
Хотя основное назначение подготавливаемого выражения заключается в том, чтобы избежать повторного разбора и планирования выражения, Digital Q.DataBase приведет к принудительному повторному анализу и перепланированию выражения перед его использованием во всех случаях, когда объекты базы данных, задействованные в выражении, претерпели изменения определений (DDL) или когда их статистика планировщика была обновлена с момента предыдущего использования подготавливаемого выражения. Кроме того, если значение search_path изменяется
от одного использования к следующему, выражение будет подвергнуто повторному разбору с использованием нового
search_path. (Такое поведение появилось в версии
Digital Q.DataBase 9.3.) Данные правила делают использование подготавливаемого выражения семантически практически эквивалентным многократной повторной отправке одного и того же текста запроса, обеспечивая при этом выигрыш в производительности, если определения объектов не меняются, особенно в случаях, когда оптимальный план остается прежним при каждом использовании. Примером отсутствия полной семантической эквивалентности может служить ситуация, когда выражение ссылается на таблицу по неквалифицированному имени, а затем создается новая таблица с тем же именем в схеме, указанной ранее в 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
инструкции с последующим ее выполнением:
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);
В данном примере тип данных второго параметра не указан,
поэтому он определяется из контекста, в котором $2 используется.
Стандарт SQL включает выражение PREPARE ,
но оно предназначено только для использования во встроенном SQL. Данная версия
PREPARE выражения также использует несколько иной
синтаксис.