选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.2 已于 2017 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

PREPARE

PREPARE — 为执行准备一个语句

大纲

PREPARE name [ ( data_type [, ...] ) ] AS statement

描述

PREPARE 创建一个预备语句。预备语句是一种服务器端对象, 可用于优化性能。执行 PREPARE 语句时,指定的语句会被解 析、分析并重写。随后发出 EXECUTE 命令时,该预备语句会 被规划并执行。这种分工避免了重复的解析分析工作,同时又允许执行计划依赖 于所提供的特定参数值。

预备语句可以带参数,也就是在执行时会代入语句中的值。创建预备语句时,可 以按位置引用参数,例如 $1$2 等。 也可以选择指定相应的参数数据类型列表。如果某个参数的数据类型未指定,或 被声明为 unknown,则其类型会从该参数第一次被引用时所 在的上下文中推断出来(如果可能)。执行该语句时,需要在 EXECUTE 语句中为这些参数提供实际值。有关详情,参见 EXECUTE

预备语句只在当前数据库会话期间存在。会话结束时,预备语句就会被遗忘,因 此再次使用前必须重新创建。这也意味着单个预备语句不能由多个并发的数据库 客户端共用;不过,每个客户端都可以创建自己要使用的预备语句。预备语句也 可以用DEALLOCATE 命令手工释放。

当单个会话要执行大量相似语句时,预备语句能带来最大的性能优势。如果 语句在规划或重写时比较复杂,例如查询涉及许多表的连接,或者需要应用多条 规则,那么这种性能差异会特别明显。如果语句相对容易规划和重写,但执行本 身代价较高,则预备语句带来的性能优势就不那么明显。

参数

name

为这个特定预备语句指定的任意名称。它在单个会话内必须唯一,随后用于执 行或释放先前已准备的语句。

data_type

预备语句中某个参数的数据类型。如果某个参数的数据类型未指定,或被指定 为 unknown,则其类型会从该参数第一次被引用时所在 的上下文中推断出来。要在预备语句本身中引用参数,可使用 $1$2 等。

statement

任何SELECTINSERTUPDATEDELETE,或VALUES 语句。

注解

如果一条预备语句被执行的次数足够多,服务器最终可能会决定保存并复用一个通用计划,而不是每次都重新规划。如果预备语句没有参数,这将立即发生;否则,只有当通用计划看起来不比依赖具体参数值的计划昂贵多少时,才会使用通用计划。通常,只有当查询的性能估计对所提供的具体参数值相当不敏感时,才会选择通用计划。

要检查PostgreSQL为预备语句使用的查询计划,请使用EXPLAIN。如果使用的是通用计划,其中会包含参数符号$n,而自定义计划中会代入当前的实际参数值。

有关查询规划以及 PostgreSQL 为此收集的统计 信息的更多内容,请参见ANALYZE文档。

可以通过查询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语句在语法上也略有不同。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。