Exempel:
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;
Om du kör tidigare skript i SSMS (tryck på Ctrl+M
-> Faktisk exekveringsplan) så får du denna exekveringsplan för den sista frågan:
I det här fallet exekveras CTE en gång för crt
alias och fem (!) gånger för prev
alias, en gång för varje rad från crt
.
Så svaret på denna fråga
är both
:en gång per fråga (crt
) och en gång per rad (prev
:en gång för varje för från crt
).
För att optimera den här frågan, till att börja med,1) Du kan försöka lagra resultaten från CTE (MyCTE
eller Query
) till en tabellvariabel eller en tillfällig tabell
2) Definiera den här tabellens primärnyckel som kopplingskolumn(erna),
3) Skriv om den sista frågan för att använda denna tabellvariabel eller temporära tabell.
Naturligtvis kan du försöka skriva om den slutliga frågan utan denna självkoppling mellan CTE.