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

sky*_*kyw 7 sql postgresql

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

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

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

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

通过类比:如果您查看窗口函数文档并假装depnameSELECT查询返回的每一行都是'develop',并且每行的平均值相同,因为平均值是在所有返回的行中计算的.平均计算多少次?

Joh*_*nis 5

根据文档第 7.2.4 节:

当使用多个窗口函数时,保证在其窗口定义中具有语法等效的 PARTITION BY 和 ORDER BY 子句的所有窗口函数在一次数据传递中进行计算。


Gor*_*off 3

您可以使用 CTE 来做您想做的事情。根据 Postgres文档

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>
Run Code Online (Sandbox Code Playgroud)