postgresql - PostgreSQL 中的 HAVING 子句是如何优化的?

标签 postgresql query-optimization

在 PostgreSQL 中,如果我们有这样的查询:

SELECT --
FROM --
WHERE -- 
GROUP BY --
HAVING
   func1 AND func2;

我认为planner中可能有三种策略:

  1. func1 首先在目标列表上执行,然后 func2 在同一个目标列表上执行
  2. func1先对目标列表执行,生成较小的结果集,然后func2对小结果集执行
  3. 假设 func1 花费 c1,func2 花费 c2,c1>c2,func2 先对 target list 执行,生成一个较小的结果集,然后 func1 对这个小结果集执行

    PostgreSQL 中的实际方法是哪一种?

最佳答案

如果任一 func 是非聚合且非 VOLATILE表达式,规划器可以有效地将它移动到 WHERE 子句。

否则,(func1 AND func2) 将作为单个过滤器表达式应用于结果组。此时,执行者的lazy boolean evaluation rules起作用;如果第一个条件的计算结果为 false,则不会执行第二个条件。因此,该行为最接近您的第二个或第三个选项,但在结果集的单次传递中执行。

评估的顺序由规划者决定,因此理论上它可能决定先执行func2。但是,我不确定什么会触发这种行为;即使 func1 的成本为 1000000000,它似乎仍然支持从左到右的计算。

EXPLAIN ANALYSE 输出将显示执行计划中应用这些条件的位置,并且通过向函数主体添加一些 RAISE NOTICE 语句,您可以观察到函数调用的确切顺序。

关于postgresql - PostgreSQL 中的 HAVING 子句是如何优化的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26233039/

相关文章:

postgresql - 显示查询结果列类型 (PostgreSQL)

sql - 如何用自定义查询替换未找到的行?

sql-server - SQL性能: does MSSQL optimise the use of date time functions or is it better to pass it as a parameter

mysql - 如何在mysql中获取前10行的总和?

mysql - 优化 MySQL - WHERE 和 ORDER BY 使用不同的列

mysql - Rails/mysql SUM 不同记录 - 优化

postgresql - 错误、系统查询、Postgresql 查询调试的不同日志文件

swift - 阿拉莫菲尔后下一个瓦尔

mysql - MySQL 中的 LEFT OUTER JOIN 与 SUBSELECT

javascript - Node.JS 回调关闭 websocket