CTE
er ikke (nødvendigvis) "aktualiseret". Det er ikke sådan, at det uundgåeligt vil kopiere alle rækker andre steder og vil udføre andre handlinger over kopien (selvom det kan opføre sig, så det optimeringsværktøjet beslutter, at det er bedre).
Hvis vi tager denne enkle forespørgsel:
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) rn
FROM mytable
) q
WHERE rn BETWEEN 101 AND 110
og se på dens plan, vil vi se noget som dette:
|--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)
Her scannes posterne (i id
rækkefølge, da tabellen er grupperet på id
), tildelt ROW_NUMBER
(det er hvad Sequence Project
gør) og videregivet til TOP
som bare stopper eksekveringen, når en bestemt tærskel er nået (110
optegnelser i vores tilfælde).
Disse 110 poster sendes til Filter
som kun sender posterne med rn
mere end 100.
Selve forespørgslen scanner kun 110
optegnelser:
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.
på 3 sider.
Lad os nu se den upaginerede forespørgsel:
SELECT *
FROM mytable
ORDER BY
id
Denne er ret enkel:læs alt fra tabellen og spyt det ud.
|--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)
At se let ud betyder dog ikke gjort let. Tabellen er ret stor, og vi skal læse mange gange for at returnere alle poster:
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.
Så i en nøddeskal ved pagineringsforespørgslen bare, hvornår den skal stoppe.