sql - 如何使 PostgresQL 优化器在绑定(bind)参数后构建执行计划?

标签 sql postgresql sql-optimization

我正在为 PostgresQL 9.1 开发 Pg/PLSQL 函数。当我在 SQL 查询中使用变量时,优化器构建了一个错误的执行计划。但是如果我用它的值替换一个变量,计划就可以了。 例如:

v_param := 100;
select count(*)
  into result
  from <some tables>
 where <some conditions>
       and id = v_param

在 3 秒内执行

select count(*)
  into result
  from <some tables>
 where <some conditions>
       and id = 100

在 300 毫秒内执行

在第一种情况下,优化器为 v_param 的任何值生成一个固定计划。

在第二种情况下,优化器根据指定的值生成一个计划,尽管不使用计划缓存,但它的效率要高得多。

是否可以让优化器在没有动态绑定(bind)的情况下生成计划,并在每次执行查询时生成计划?

最佳答案

Tom Lane 在 just-released PostgreSQL 9.2 中对此进行了显着改进;见What's new in PostgreSQL 9.2特别是:

Prepared statements used to be optimized once, without any knowledge of the parameters' values. With 9.2, the planner will use specific plans regarding to the parameters sent (the query will be planned at execution), except if the query is executed several times and the planner decides that the generic plan is not too much more expensive than the specific plans.

这是一个长期存在且痛苦的问题,以前需要 SET enable_... 参数,使用 EXECUTE 的包装函数,或其他丑陋的技巧。现在它应该“正常工作”。

升级。

对于阅读本文的任何其他人,您可以判断这个问题是否困扰着您,因为参数化/准备好的查询的auto_explain 计划将不同于您解释问问自己。要验证,请尝试 PREPARE ... SELECT 然后 EXPLAIN EXECUTE 并查看您是否得到与 EXPLAIN SELECT 不同的计划。

另见 this prior answer .

关于sql - 如何使 PostgresQL 优化器在绑定(bind)参数后构建执行计划?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12368338/

相关文章:

c# - 如何在 C# 中的 SQL 查询中包含变量

mysql - 优化大 `IN` SQL

sql-server - SQL 服务器 : Selective XML Index not being efficiently used

mysql - 将 IN 子查询重写为 JOIN

php - 从列中选择唯一值

.NET GridView 更新不会将 UserID 发送到 SQL 查询

mysql - MyIsam 针对多个 %term% 进行全文搜索

SQL检查是否存在多个

postgresql - JPA 和 PostqreSQL : long string persistence

javascript - 使用 postgresql 从 url 加载图像,但只填充文本链接