Esempio:
SET NOCOUNT ON;
SET IMPLICIT_TRANSACTIONS ON;
CREATE TABLE MyTable (MyID INT PRIMARY KEY);
GO
INSERT MyTable (MyID)
VALUES (11), (22), (33), (44), (55);
PRINT 'Test MyCTE:';
WITH MyCTE
AS (
SELECT *, ROW_NUMBER()OVER(ORDER BY MyID) AS RowNum
FROM MyTable
)
SELECT *
FROM MyCTE crt
LEFT JOIN MyCTE prev ON crt.RowNum=prev.RowNum+1;
ROLLBACK;
Se esegui lo script precedente in SSMS (premi Ctrl+M
-> Piano di esecuzione effettivo), quindi otterrai questo piano di esecuzione per l'ultima query:
In questo caso, il CTE viene eseguito una volta per crt
alias e cinque (!) volte per prev
alias, una volta per ogni riga da crt
.
Quindi, la risposta a questa domanda
è both
:una volta per query (crt
) e una volta per riga (prev
:una volta per ogni da crt
).
Per ottimizzare questa query, per cominciare,1) Puoi provare a memorizzare i risultati da CTE (MyCTE
o Query
) in una variabile di tabella o in una tabella temporanea
2) Definisci la chiave primaria di questa tabella come colonna/e di join,
3) Riscrivi la query finale per utilizzare questa variabile di tabella o tabella temporanea.
Naturalmente, puoi provare a riscrivere la query finale senza questo collegamento automatico tra CTE.