sql-server – 此查询如何在执行计划中生成两个连接运算符?

在empno上具有集群唯一索引的表结构.

CREATE TABLE [dbo].[EMP](
    [EMPNO] [int] NOT NULL,
    [ENAME] [varchar](10) NULL,
    [JOB] [varchar](9) NULL,
    [MGR] [int] NULL,
    [HIREDATE] [datetime] NULL,
    [SAL] [int] NULL,
    [COMM] [int] NULL,
    [DEPTNO] [int] NULL
) ON [PRIMARY]

询问

SELECT sal,sum(sal) over(PARTITION BY empno)
FROM emp

查询计划

最佳答案
带窗口聚合的计划通常使用公共子表达式假脱机.这种类型的计划很好地写在这里Partitioning and the Common Subexpression Spool

假设该表具有以下行

CREATE TABLE [dbo].[EMP](
    [EMPNO] [int] NOT NULL,
    [SAL] [int] NULL) 

INSERT INTO [dbo].[EMP] 
VALUES (1,1),
       (1,2), 
       (1,3),
       (1,4), 
       (2,1),
       (2,2)

它总共有6行,有2个不同的EMPNO值.显示实际发出的行数的实际执行计划如下.

计划顶部的段迭代器为通过它的行添加一个标志,指示它何时是新分区的开始(即,empno已更改).

其左侧的线轴(主线轴)从段迭代器一次获取一行,并将其插入tempdb中的工作表中.一旦获得标志说新组已经启动它就会返回一行到嵌套循环运算符的顶部输入.

这会导致在工作表中的行(计划中的辅助假脱机)上调用流聚合,计算SUM([SAL]),然后将此值与工作表中的行(第三个假脱机运算符)连接起来在计划中)之前工作表被截断为新组准备好了.

主段假脱机发出一个虚拟行,以便处理最后一组,这就是为什么实际发出的行数显示为3(组数加1)

转载注明原文:sql-server – 此查询如何在执行计划中生成两个连接运算符? - 代码日志