2013-04-14 13 views

risposta

3

piani con aggregati finestrate normalmente utilizzare un comune sub espressione rocchetto. Una buona scrittura piano di questo tipo di piano è qui Partitioning and the Common Subexpression Spool

Supponiamo che la tabella include le seguenti righe

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) 

Ha 6 righe in totale con 2 distinti EMPNO valori. Di seguito è riportato il piano di esecuzione effettivo che mostra il numero effettivo di righe emesse.

enter image description here

L'iteratore segmento nella parte superiore del piano aggiunge un flag alle righe che passano attraverso di essa indica quando è l'inizio di una nuova partizione (cioè il empno è cambiato).

Lo spool a sinistra immediata (spool primario) riceve una riga alla volta dall'iteratore di segmento e la inserisce in una tabella di lavoro in tempdb. Una volta che ottiene la bandiera che dice che un nuovo gruppo ha iniziato, restituisce una riga all'ingresso superiore dell'operatore dei cicli nidificati.

Questo fa sì che l'aggregazione del flusso venga invocata sulle righe nella tabella di lavoro (spool secondario nel piano), lo SUM([SAL]) viene calcolato quindi questo valore viene unito di nuovo con le righe nella tabella di lavoro (il terzo operatore di spool in il piano) prima che il tavolo di lavoro sia troncato pronto per il nuovo gruppo.

Il rocchetto segmento primario emette una riga fittizia per ottenere il gruppo finale elaborato motivo per cui il numero effettivo di righe emesse è indicata come 3 (numero di gruppi più uno)

0

funzioni aggregate in OVER clausola può essere riscritto in questo modo: FROM table AS x INNER JOIN (SELECT partition columns, AggregateWithoutOverClause (...) ... FROM ...) AS y ON x.PartitionColumns = y.PartitionColumns (se le colonne di partizione sono obbligatorie - NOT NULL).

Esempio:

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; 

Risultati:

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. 

I piani di esecuzione: enter image description here

Questo sarà solo spiegare l'ultima unirsi: enter image description here

La spiegazione per è la prima volta in nella sezione Elaborazione per gruppo/Partitioning and the Common Subexpression Spool.