To zależy.
Przede wszystkim
Co to jest wspólne wyrażenie tabelowe?
(Nierekurencyjne) CTE jest traktowane bardzo podobnie do innych konstrukcji, które mogą być również używane jako wbudowane wyrażenia tabelowe w SQL Server. Tabele pochodne, widoki i funkcje o wartościach w tabeli wbudowanej. Zauważ, że chociaż BOL mówi, że CTE „można traktować jako tymczasowy zestaw wyników”, jest to opis czysto logiczny. Najczęściej nie jest on materializowany sam w sobie.
Co to jest stół tymczasowy?
Jest to zbiór wierszy przechowywanych na stronach danych w tempdb. Strony danych mogą znajdować się częściowo lub w całości w pamięci. Dodatkowo tabela tymczasowa może być indeksowana i zawierać statystyki kolumn.
Dane testowe
CREATE TABLE T(A INT IDENTITY PRIMARY KEY, B INT , F CHAR(8000) NULL);
INSERT INTO T(B)
SELECT TOP (1000000) 0 + CAST(NEWID() AS BINARY(4))
FROM master..spt_values v1,
master..spt_values v2;
Przykład 1
WITH CTE1 AS
(
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
)
SELECT *
FROM CTE1
WHERE A = 780
Zauważ, że w powyższym planie nie ma wzmianki o CTE1. Po prostu uzyskuje bezpośredni dostęp do tabel podstawowych i jest traktowany tak samo jak
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
WHERE A = 780
Przepisywanie przez zmaterializowanie CTE w pośredniej tabeli tymczasowej byłoby bardzo nieproduktywne.
Materializacja definicji CTE
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
Wymagałoby to skopiowania około 8 GB danych do tabeli tymczasowej, ale nadal istnieje ryzyko wybrania z niej.
Przykład 2
WITH CTE2
AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0)
SELECT *
FROM CTE2 T1
CROSS APPLY (SELECT TOP (1) *
FROM CTE2 T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
Powyższy przykład zajmuje około 4 minut na moim komputerze.
Tylko 15 wierszy z 1 000 000 losowo wygenerowanych wartości pasuje do predykatu, ale kosztowne skanowanie tabeli odbywa się 16 razy, aby je zlokalizować.
Byłby to dobry kandydat do zmaterializowania wyniku pośredniego. Odpowiednie przepisanie tabeli temp zajęło 25 sekund.
INSERT INTO #T
SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0
SELECT *
FROM #T T1
CROSS APPLY (SELECT TOP (1) *
FROM #T T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
Pośrednia materializacja części zapytania do tabeli tymczasowej może czasami być przydatna, nawet jeśli jest oceniana tylko raz - gdy pozwala na ponowną kompilację reszty zapytania z wykorzystaniem statystyk dotyczących zmaterializowanego wyniku. Przykładem tego podejścia jest artykuł dotyczący SQL Cat Kiedy rozbijać złożone zapytania.
W pewnych okolicznościach SQL Server użyje spool do buforowania wyniku pośredniego, np. CTE i uniknąć konieczności ponownej oceny tego poddrzewa. Zostało to omówione w (zmigrowanym) elemencie Połącz. Podaj wskazówkę, jak wymusić pośrednią materializację CTE lub tabel pochodnych. Jednak nie są tworzone żadne statystyki na ten temat i nawet jeśli liczba buforowanych wierszy miałaby znacznie różnić się od oszacowanej, nie jest możliwe, aby plan wykonania w toku dynamicznie dostosowywał się w odpowiedzi (przynajmniej w obecnych wersjach. Adaptacyjne plany zapytań mogą stać się możliwe w przyszłość).