Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

L'istruzione WITH viene eseguita una volta per query o una volta per riga?

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.