SQL 服务器:使用具有相同 OVER 子句的多个 aggregate/analytic 函数?

SQL Server: Use multiple aggregate/analytic functions with same OVER clause?

以下SQL服务器查询:

SELECT DISTINCT NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0) as dt_hour
,AVG(Availability)  
    OVER (PARTITION BY NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0)) AS avg  
,PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY Availability)  
    OVER (PARTITION BY NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0)) AS perc90  
,MAX(Availability)  
    OVER (PARTITION BY NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0)) AS max  
FROM InterfaceAvailability_CS_Detail_hist
order by NodeID, dt_hour;

到 运行 的时间大约是这个时间的 3 倍:

SELECT DISTINCT NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0) as dt_hour
,PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY Availability)  
    OVER (PARTITION BY NodeID, dateadd(hour, datediff(hour, 0, Timestamp), 0)) AS perc90  
FROM InterfaceAvailability_CS_Detail_hist
order by NodeID, dt_hour;

我怀疑它对每个聚合进行了冗余分区(AVGPERCENTILE_CONTMAX)。有没有办法只编写一次 OVER 子句并将其应用于每个聚合?

在没有看到查询计划的情况下,很难判断发生了什么,但我的猜测是,通过在 parititon by 子句中使用标量函数,您限制了 sql服务器可以做查询优化。

我尝试了一个类似的查询,并通过使用 CTE 为 dt_hour 列生成值,我能够生成一个排序、嵌套较少的计划循环和流聚合操作。由于我不知道您的原始查询中这些操作的成本,因此我不知道这是否会产生更好的结果,因为仅仅在计划中看到更少的东西并不一定意味着改进。

WITH processed AS (
    SELECT *, dateadd(hour, datediff(hour, 0, Timestamp), 0) as dt_hour
    FROM InterfaceAvailability_CS_Detail_hist
)
SELECT DISTINCT NodeID, dt_hour
,AVG(Availability)  
    OVER (PARTITION BY NodeID, dt_hour) AS avg  
,PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY Availability)  
    OVER (PARTITION BY NodeID, dt_hour) AS perc90  
,MAX(Availability)  
    OVER (PARTITION BY NodeID, dt_hour) AS max  
FROM processed
order by NodeID, dt_hour;