Beispiel:
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;
Wenn Sie das vorherige Skript in SSMS ausführen (drücken Sie Ctrl+M
-> Tatsächlicher Ausführungsplan), dann erhalten Sie diesen Ausführungsplan für die letzte Abfrage:
In diesem Fall wird der CTE einmal für crt
ausgeführt Alias und fünf (!) Mal für prev
Alias, einmal für jede Zeile von crt
.
Also, die Antwort auf diese Frage
ist both
:einmal pro Abfrage (crt
) und einmal pro Zeile (prev
:einmal für jeden von crt
).
Um diese Abfrage zunächst zu optimieren,1) können Sie versuchen, die Ergebnisse von CTE (MyCTE
) zu speichern oder Query
) in eine Tabellenvariable oder eine temporäre Tabelle
2) Definieren Sie den Primärschlüssel dieser Tabelle als Join-Spalte(n),
3) Schreiben Sie die letzte Abfrage neu, um diese Tabellenvariable oder temporäre Tabelle zu verwenden.
Natürlich können Sie versuchen, die endgültige Abfrage ohne diese Selbstverknüpfung zwischen CTE neu zu schreiben.