SQL窗口函数:返回相同avg()多次的性能影响?

时间:2013-05-02 16:48:28

标签: sql postgresql

我想从表A中选择一堆行,以及像avg(A.price)和avg(A.distance)这样的聚合函数的结果。

现在,SELECT查询需要花费大量时间,所以我不想运行一个查询来获取行,而另一个查询需要获取平均值。如果我这样做,我将运行查询以选择两次适当的行。

但是看看PostgreSQL窗口函数文档(http://www.postgresql.org/docs/9.1/static/tutorial-window.html),似乎使用window函数返回我想要与返回行一起使用的聚合函数的结果意味着返回的每一行都包含聚合函数的结果。在我的情况下,由于聚合遍及主SELECT查询返回的所有行而不是其行的子集,这看起来很浪费。

多次返回相同的avg()会有什么性能影响,因为我在A中选择了行的子集但是在整个子集中进行聚合查询?特别是,Postgres每次都会重新计算平均值,还是以某种方式缓存平均值?

通过类比:如果你查看窗口函数文档并假装depname对于SELECT查询返回的每一行都是'develop',并且每行的平均值是相同的,因为平均值计算了所有返回的行。这个平均值计算了多少次?

1 个答案:

答案 0 :(得分:3)

您可以使用CTE做您想做的事。根据Postgres documentation

  

WITH查询的一个有用属性是它们只被评估一次   每次执行父查询,即使它们被引用更多   父查询或兄弟WITH查询不止一次。因此,昂贵   多个地方所需的计算可以放在一个地方   WITH查询以避免冗余工作。另一个可能的应用是   防止对副作用的功能进行多余的评估。   然而,这个硬币的另一面是优化器更少   能够将父查询中的限制推送到WITH查询   比普通的子查询。通常会评估WITH查询   如上所述,不抑制父查询可能的行   之后丢弃。 (但是,如上所述,评估可能会停止   早期如果查询的引用只需要有限的数量   行。)

您可以使用以下结构构建最终结果:

with cte as (your basic select goes here)
select *
from cte cross join
     (select averages here
      from cte
     ) const
where < your row filter here>