在 PostgreSQL 中,如果我们有这样的查询:
SELECT --
FROM --
WHERE --
GROUP BY --
HAVING
func1 AND func2;
我认为planner中可能有三种策略:
- func1 首先在目标列表上执行,然后 func2 在同一个目标列表上执行
- func1先对目标列表执行,生成较小的结果集,然后func2对小结果集执行
假设 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/