To záleží.
Za prvé
Co je běžný tabulkový výraz?
S (nerekurzivním) CTE se zachází velmi podobně jako s jinými konstrukcemi, které lze také použít jako výrazy vložené tabulky na serveru SQL Server. Odvozené tabulky, pohledy a funkce s hodnotou vložené tabulky. Všimněte si, že zatímco BOL říká, že CTE „lze považovat za dočasnou sadu výsledků“, jde o čistě logický popis. Častěji není zhmotněna sama o sobě.
Co je to dočasná tabulka?
Toto je kolekce řádků uložených na datových stránkách v databázi tempdb. Datové stránky mohou být částečně nebo zcela uloženy v paměti. Dočasná tabulka může být navíc indexována a může mít statistiku sloupců.
Testovací data
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;
Příklad 1
WITH CTE1 AS
(
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
)
SELECT *
FROM CTE1
WHERE A = 780
Upozornění ve výše uvedeném plánu není žádná zmínka o CTE1. Pouze přistupuje přímo k základním tabulkám a je s ním zacházeno stejně jako
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
WHERE A = 780
Přepsání zhmotněním CTE do přechodné dočasné tabulky by bylo značně kontraproduktivní.
Zhmotnění definice CTE pro
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
Zahrnovalo by to zkopírování asi 8 GB dat do dočasné tabulky, pak je tu také režie na výběr z ní.
Příklad 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
Výše uvedený příklad trvá na mém počítači asi 4 minuty.
Pouze 15 řádků z 1 000 000 náhodně vygenerovaných hodnot odpovídá predikátu, ale drahé prohledání tabulky proběhne 16krát, aby je bylo možné najít.
To by byl dobrý kandidát pro zhmotnění průběžného výsledku. Přepsání ekvivalentní dočasné tabulky trvalo 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
Průběžná materializace části dotazu do dočasné tabulky může být někdy užitečná, i když je vyhodnocena pouze jednou – když umožňuje rekompilaci zbytku dotazu s využitím statistik o materializovaném výsledku. Příklad tohoto přístupu je v článku SQL Cat When To Break Down Complex Queries.
Za určitých okolností SQL Server použije zařazování do mezipaměti mezivýsledků, např. CTE a vyhnout se nutnosti přehodnocování tohoto podstromu. To je diskutováno v položce (migrované) Connect Poskytnout nápovědu k vynucení přechodné materializace CTE nebo odvozených tabulek. Nejsou však o tom vytvářeny žádné statistiky, a i kdyby se počet řádků pro souběžný tisk měl výrazně lišit od odhadovaného, není možné, aby se probíhající plán provádění dynamicky přizpůsoboval v reakci (alespoň v aktuálních verzích. Adaptivní plány dotazů mohou být možné v budoucnost).