2013-04-14 38 views
5

在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 

查詢計劃

enter image description here

回答

3

計劃與窗口聚集體通常使用公共子表達式卷軸上。這種類型的方案中的一個好的寫入最多是這裏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值。顯示實際排放行數的實際執行計劃如下。

enter image description here

在計劃的頂部段迭代添加一個標誌,以通過它的指示時,它是一個新的分區的開始(即,empno已經改變)的行。

位於其左側(主卷軸)的卷軸每次從段迭代器獲取一行並將其插入到tempdb中的工作表中。一旦它得到標誌說新組已經開始,它會向嵌套循環運算符的頂部輸入返回一行。

這會導致在工作表中的行(計劃中的輔助假脫機部分)上調用流聚合,然後計算SUM([SAL]),然後將此值與工作表中的行(第三個假脫機操作符在工作表被截斷爲新組準備好之前)。

主段線軸發出虛設行,以獲得處理後的最終基團,其是爲什麼被示出爲3(組數加1)

0

OVER子句集合函數發射的實際行數可以如下所示:從表AS x INNER JOIN(選擇分區列,AggregateWithoutOverClause(...)... FROM ...)AS y ON x.PartitionColumns = y.PartitionColumns(如果分區列是必需的 - NOT NULL)。

例子:

SET STATISTICS IO ON; 
SET NOCOUNT ON; 

-- OP's query 
SELECT sal,sum(sal) over(PARTITION BY empno) 
FROM emp; 

-- Reqwriten query 
SELECT a.sal, b.SumSal 
FROM emp a 
INNER JOIN (SELECT EMPNO, SUM(sal) AS SumSal FROM emp GROUP BY EMPNO) b ON a.EMPNO = b.EMPNO; 

結果:

sal   
----------- ----------- 
1   10 
2   10 
3   10 
4   10 
1   3 
2   3 

Table 'Worktable'. Scan count 3, logical reads 21, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'EMP'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

sal   SumSal 
----------- ----------- 
1   10 
2   10 
3   10 
4   10 
1   3 
2   3 

Table 'Worktable'. Scan count 3, logical reads 21, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'EMP'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

執行計劃: enter image description here

這僅說明了最後一個加入enter image description here

有關第一次加入的說明可在每組處理/ Partitioning and the Common Subexpression Spool的部分中找到。