Przykład:
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;
Jeśli uruchamiasz poprzedni skrypt w SSMS (naciśnij Ctrl+M
-> Actual Execution Plan) to otrzymasz ten plan wykonania dla ostatniego zapytania:
W tym przypadku CTE jest wykonywane jeden raz dla crt
alias i pięć (!) razy dla prev
alias, raz na każdy wiersz z crt
.
Tak więc odpowiedź na to pytanie
to both
:raz na zapytanie (crt
) i raz na wiersz (prev
:raz na każdy dla od crt
).
Aby zoptymalizować to zapytanie, na początek1) Możesz spróbować zapisać wyniki z CTE (MyCTE
lub Query
) do zmiennej tabeli lub tabeli tymczasowej
2) Zdefiniuj klucz podstawowy tej tabeli jako kolumny łączenia,
3) Przepisz ostatnie zapytanie, aby użyć tej zmiennej tabeli lub tabeli tymczasowej.
Oczywiście możesz spróbować przepisać ostatnie zapytanie bez tego samodzielnego łączenia między CTE.