窗口函数:Rows Unbounded Preceeding 的目的是什么?

J.D*_*.D. 5 sql-server window-functions sql-server-2017

在窗口函数中使用 Rows Unbounded Preceeding 子句的目的是什么?我想我明白它基本上是说在汇总聚合函数时不限制回溯多远,但这与根本不使用该子句有什么不同?

您能否提供一个示例来说明以下之间的区别:

SUM(ColumnA) OVER (PARTITION BY ColumnB ORDER BY ColumnC DESC ROWS UNBOUNDED PRECEEDING)

SUM(ColumnA) OVER (PARTITION BY ColumnB ORDER BY ColumnC DESC)

注意:我的问题是在以下行没有上限的上下文中。

Eri*_*ing 5

行和范围之间的语义差异

如果我们查看这个查询的结果,很容易看出我们什么时候可能想要检查使用范围或行。

SELECT   OwnerUserId,
         CAST(CreationDate AS DATE) AS DumbedDownDate,
         Score,
         SUM(Score) OVER 
                   ( ORDER BY CAST(CreationDate AS DATE)) AS Not_Specified,
         SUM(Score) OVER 
                   ( ORDER BY CAST(CreationDate AS DATE) RANGE UNBOUNDED PRECEDING ) AS Range_Specified,
         SUM(Score) OVER 
                   ( ORDER BY CAST(CreationDate AS DATE) ROWS UNBOUNDED PRECEDING ) AS Rows_Specified
FROM     dbo.Posts
WHERE    OwnerUserId = 1
AND      CAST(CreationDate AS DATE) BETWEEN '2008-08-01' AND '2008-08-31'
ORDER BY DumbedDownDate;
Run Code Online (Sandbox Code Playgroud)

当未设置边界时,结果与我们特别要求 a 的结果相同RANGE。要求给ROWS了我们一个不同的结果。

ROWS结果更像是一个运行总数,而RANGE结果是为...行的范围内的总价值。

坚果

表现

如果使用行,则窗口假脱机操作符可以使用内存工作表。Range 使用磁盘工作表,有时速度较慢。

比较这两个查询:

SELECT   OwnerUserId,
         CreationDate,
         Score,
         SUM(Score) 
             OVER ( ORDER BY CreationDate RANGE UNBOUNDED PRECEDING ) AS Range_Specified
FROM     dbo.Posts
WHERE    OwnerUserId <= 22656
AND      CreationDate >= '20080101' 
AND      CreationDate < '20150101'
ORDER BY CreationDate;


SELECT   OwnerUserId,
         CreationDate,



         Score,
         SUM(Score) 
             OVER ( ORDER BY CreationDate ROWS UNBOUNDED PRECEDING ) AS Rows_Specified
FROM     dbo.Posts
WHERE    OwnerUserId <= 22656
AND      CreationDate >= '20080101' 
AND      CreationDate < '20150101'
ORDER BY CreationDate;
Run Code Online (Sandbox Code Playgroud)

它们的查询计划显示了 Window Spool 完全不同的时间:

坚果

如果我们查看两个查询的 STATISTICS IO 输出,它们也大不相同:

Table 'Worktable'. Scan count 1363952, logical reads 11944334, physical reads 0, 
read-ahead reads 3884, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Posts'. Scan count 5, logical reads 4722714, physical reads 0, read-ahead 
reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

对比

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, 
read-ahead reads 3884, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Posts'. Scan count 5, logical reads 4723890, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

批处理模式

在 SQL Server 2019 中,批处理模式通常可用于行存储查询,或者在 SQL Server 2016/2017 中,有多种方法可以将批处理模式处理引入行存储查询,由于添加了批处理模式窗口聚合。

请在此处查看 Itzik Ben-Gan 先生的三部分系列文章: