VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

PREPARE

PREPARE - 为执行准备一个语句

语法格式

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

说明

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

预处理语句可以使用参数说明:在执行语句时替换为语句的值。创建预准备语句时,请使用$1 , $2等按位置引用参数说明。可以选择指定相应的参数说明数据类型列表。如果未指定参数说明的数据类型或将其声明为unknown,则从首次引用该参数说明的上下文(如果可能)推断出该类型。执行语句时,请在EXECUTE 语句中指定这些参数说明的实际值。有关更多信息,请参阅EXECUTE。

准备语句仅持续当前数据库会话的持续时间。会话结束时,忘记了准备好的语句,因此必须重新创建它才能再次使用。这也意味着多个并发数据库客户端不能使用单个预准备语句;但是,每个客户端都可以创建自己准备好的语句来使用。可以使用DEALLOCATE命令手动清除准备好的语句。

当使用单个会话执行大量类似语句时,准备语句可能具有最大的性能优势。如果声明计划或重写很复杂,例如,性能差异将特别显着。如果查询涉及许多表的连接或需要应用多个规则。如果语句的计划和重写相对简单,但执行起来相对昂贵,那么预处理语句的性能优势就不那么明显了。

参数说明

  • name

    给予此特定预处理语句的任意名称。它在单个会话中必须是唯一的,并且随后用于执行或取消分配先前准备的语句。

  • data_type

    准备好的语句的参数说明的数据类型。如果未指定特定参数说明的数据类型或将其指定为unknown,则将从首次引用该参数说明的上下文中推断出该数据类型。要引用预准备语句本身中的参数说明,请使用$1 , $2 等。

  • statement

    任何 SELECT ,_ INSERT , UPDATE , DELETE 或 VALUES 语句。

注意事项

准备好的语句可以使用通用计划,而不是使用每组提供的 EXECUTE值重新计划。对于没有参数说明的预处理语句,这会立即发生;否则只有在五次或更多次执行产生计划后才会发生,其计划的估计成本(包括计划开销)比通用计划成本估算更昂贵。选择通用计划后,它将用于准备好的声明的剩余生命周期。使用EXECUTE值在具有许多重复项的列中很少见,可以生成比通用计划便宜得多的自定义计划,即使在添加计划开销之后,也可能永远不会使用通用计划。

通用计划假定提供给 EXECUTE的每个值都是列的不同值之一,并且列值是均匀分布的。例如,如果统计信息记录三个不同的列值,则通用计划假定列相等性比较将匹配33%的已处理行。列统计信息还允许通用计划准确计算唯一列的选择性。非均匀分布列的比较和不存在的值的规范会影响平均计划成本,因此会影响是否以及何时选择通用计划。

要检查Vastbase E100用于准备语句的查询计划,请使用 EXPLAIN,例如EXPLAIN EXECUTE 。如果正在使用通用计划,它将包含参数说明符号 $n,而自定义计划将提供的参数说明值替换为它。通用计划中的行估计反映了为参数说明计算的选择性。

有关查询计划和Vastbase E100为此目的收集的统计信息的更多信息,请参阅ANALYZE文档。

虽然准备语句的要点是避免重复的语句分析和语句规划,但只要语句中使用的数据库对象经历了定义(DDL)更改,Vastbase E100就会强制重新分析和重新规划语句。自从上次使用准备好的声明以来。此外,如果search_path的值从一次使用更改为下一次使用,则将使用新的search_path 重新解析该语句。 (后者的行为在Vastbase E100 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的上下文中推断出它。