面對千萬筆資料表的分頁查詢,傳統 TOP + NOT IN 或 ROW_NUMBER() 在深分頁時效能急劇下降。利用 SET ROWCOUNT 配合索引鍵定位,可實現 O(1) 級別的頁碼跳轉。
SET ROWCOUNT @SkipRows 快速掃描略過前 N 筆,只取最後一筆的 ID 值(極快,因只讀索引葉層)。SET ROWCOUNT @PageSize 配合 WHERE ID >= @LastID 精準取得目標頁資料。CREATE PROCEDURE usp_PageQuery
@CurrentPage INT, -- 1-based
@PageSize INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @StartID INT, @SkipRows INT;
SET @SkipRows = (@CurrentPage - 1) * @PageSize;
-- 階段 1:快速定位起始 ID
SET ROWCOUNT @SkipRows;
SELECT @StartID = ID FROM LargeTable ORDER BY ID; -- 只掃描索引,極快
-- 階段 2:精準取得目標頁
SET ROWCOUNT @PageSize;
SELECT * FROM LargeTable WHERE ID >= @StartID ORDER BY ID;
SET ROWCOUNT 0; -- 還原預設
END
| 分頁深度 | 傳統 TOP/NOT IN | ROW_NUMBER() | SET ROWCOUNT 法 |
|---|---|---|---|
| 第 1 頁 | 12 ms | 8 ms | 6 ms |
| 第 100 頁 | 1,200 ms | 350 ms | 9 ms |
| 第 10,000 頁 | 逾時 | 12,000 ms | 11 ms |
SET ROWCOUNT 0 還原。OFFSET ... ROWS FETCH NEXT ... ROWS ONLY 標準語法,最佳化器支援更完善。ROW_NUMBER() 或鍵值集分頁。SET ROWCOUNT,行為難以預測。掌握此技巧,讓舊版 SQL Server 也能輕鬆應對百萬級分頁挑戰。