CTE
không (nhất thiết) được "thực tế hóa". Không phải là nó chắc chắn sẽ sao chép tất cả các hàng ở nơi khác và sẽ thực hiện các thao tác khác trên bản sao (mặc dù nó có thể hoạt động để trình tối ưu hóa quyết định nó tốt hơn).
Nếu chúng ta thực hiện truy vấn đơn giản này:
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) rn
FROM mytable
) q
WHERE rn BETWEEN 101 AND 110
và nhìn vào kế hoạch của nó, chúng ta sẽ thấy một cái gì đó như thế này:
|--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)
Tại đây, các bản ghi được quét (trong id
sắp xếp như bảng được nhóm trên id
), đã chỉ định ROW_NUMBER
(đây là những gì Sequence Project
hiện) và được chuyển đến TOP
điều này chỉ tạm dừng thực thi khi đạt đến một ngưỡng nhất định (110
hồ sơ trong trường hợp của chúng tôi).
110 bản ghi đó được chuyển đến Filter
mà chỉ chuyển các bản ghi với rn
lớn hơn 100.
Bản thân truy vấn chỉ quét 110
hồ sơ:
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.
trong 3 trang.
Bây giờ chúng ta hãy xem truy vấn không được gắn thẻ:
SELECT *
FROM mytable
ORDER BY
id
Cái này khá đơn giản:đọc mọi thứ từ bảng và nhổ nó ra.
|--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)
Tuy nhiên, nhìn dễ không có nghĩa là thực hiện dễ dàng. Bảng này khá lớn và chúng ta cần thực hiện nhiều lần đọc để trả về tất cả các bản ghi:
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.
Vì vậy, tóm lại, truy vấn phân trang chỉ biết khi nào nên dừng.