Příklad:
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;
Pokud spustíte předchozí skript v SSMS (stiskněte Ctrl+M
-> Skutečný plán provádění), pak získáte tento plán provádění pro poslední dotaz:
V tomto případě se CTE provede jednou pro crt
alias a pět (!) krát pro prev
alias, jednou pro každý řádek z crt
.
Takže odpověď na tuto otázku
je both
:jednou na dotaz (crt
) a jednou na řádek (prev
:jednou za každý z crt
).
Chcete-li tento dotaz optimalizovat, pro začátek,1) Můžete zkusit uložit výsledky z CTE (MyCTE
nebo Query
) do proměnné tabulky nebo dočasné tabulky
2) Definujte primární klíč této tabulky jako sloupec(y) spojení
3) Přepište poslední dotaz tak, aby používal tuto proměnnou tabulky nebo dočasnou tabulku.
Samozřejmě se můžete pokusit přepsat konečný dotaz bez tohoto vlastního spojení mezi CTE.