CTE
není (nezbytně) "aktualizovaný". Nejde o to, že nevyhnutelně zkopíruje všechny řádky jinam a bude nad kopií provádět další operace (i když se může chovat tak, že optimalizátor rozhodne, že je to lepší).
Pokud vezmeme tento jednoduchý dotaz:
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) rn
FROM mytable
) q
WHERE rn BETWEEN 101 AND 110
a podívejte se na jeho plán, uvidíme něco takového:
|--Filter(WHERE:([Expr1003]>=(101) AND [Expr1003]<=(110)))
|--Top(TOP EXPRESSION:(CASE WHEN (110) IS NULL OR (110)<(0) THEN (0) ELSE (110) END))
|--Sequence Project(DEFINE:([Expr1003]=row_number))
|--Segment
|--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)
Zde jsou záznamy naskenovány (v id
pořadí, protože tabulka je seskupená na id
), přiřazeno číslo ROW_NUMBER
(toto je Sequence Project
dělá) a předán do TOP
který pouze zastaví provádění při dosažení určité prahové hodnoty (110
v našem případě záznamy).
Těchto 110 záznamů je předáno do Filter
který pouze předává záznamy s rn
větší než 100.
Samotný dotaz skenuje pouze 110
záznamy:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
(строк обработано: 10)
Table 'mytable'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
na 3 stránkách.
Nyní se podívejme na nestránkovaný dotaz:
SELECT *
FROM mytable
ORDER BY
id
Tohle je docela jednoduché:přečtěte si vše ze stolu a vyplivněte to.
|--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)
Nicméně, hledat snadno neznamená udělat snadno. Tabulka je poměrně velká a musíme provést mnoho čtení, abychom vrátili všechny záznamy:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(строк обработано: 1310720)
Table 'mytable'. Scan count 1, logical reads 2765, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 266 ms, elapsed time = 11690 ms.
Stručně řečeno, stránkovací dotaz prostě ví, kdy přestat.