Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

L'instruction WITH s'exécute-t-elle une fois par requête ou une fois par ligne ?

Exemple :

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;

Si vous exécutez le script précédent dans SSMS (appuyez sur Ctrl+M -> Actual Execution Plan) alors vous obtiendrez ce plan d'exécution pour la dernière requête :

Dans ce cas, le CTE est exécuté une fois pour crt alias et cinq (!) fois pour prev alias, une fois pour chaque ligne de crt .

Donc, la réponse à cette question

est both :une fois par requête (crt ) et une fois par ligne (prev :une fois pour chaque for de crt ).

Pour optimiser cette requête, pour commencer,1) Vous pouvez essayer de stocker les résultats de CTE (MyCTE ou Query ) dans une variable de table ou une table temporaire

2) Définissez la clé primaire de cette table comme étant la ou les colonnes de jointure,

3) Réécrivez la requête finale pour utiliser cette variable de table ou cette table temporaire.

Bien sûr, vous pouvez essayer de réécrire la requête finale sans cette auto-jointure entre CTE.