首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 高效分頁技巧:SET ROWCOUNT 實作大資料量分頁預存程序

     編輯:關於SqlServer

分頁挑戰

傳統 TOP N + NOT IN 或雙層 TOP 寫法,在資料量達百萬筆以上時效能急遽下降。SQL Server 2000/2005 時代,利用 SET ROWCOUNT 限制掃描範圍,是高效分頁的經典技巧。

核心邏輯

  1. 設定 ROWCOUNT = @startRowIndex,依排序順序掃描至目標頁首筆,取得其主鍵值 @first_id。
  2. 設定 ROWCOUNT = @maximumRows,查詢 WHERE id >= @first_id 取得該頁資料。
  3. 重設 ROWCOUNT = 0 還原預設。

完整預存程式碼

CREATE PROCEDURE usp_PageResults_NAI
    @startRowIndex INT,   -- 起始列索引 (0-based)
    @maximumRows INT      -- 每頁筆數
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @first_id INT;

    -- 1. 定位首筆主鍵
    SET ROWCOUNT @startRowIndex;
    SELECT @first_id = EmployeeID FROM Employees ORDER BY EmployeeID;

    -- 2. 取得該頁資料
    SET ROWCOUNT @maximumRows;
    SELECT e.*, d.Name AS DepartmentName
    FROM Employees e
    INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID
    WHERE EmployeeID >= @first_id
    ORDER BY e.EmployeeID;

    -- 3. 還原
    SET ROWCOUNT 0;
END
GO

關鍵前提與限制

  • ✅ 主鍵唯一且連續遞增 (IDENTITY) — 確保 WHERE id >= @first_id 精確命中頁首。
  • ✅ 排序欄位 = 主鍵 — 若需其他欄位排序,需調整邏輯 (如加入 ROW_NUMBER)。
  • ⚠️ SET ROWCOUNT 影響範圍:會影響後續所有陳述式 (含觸發器),務必在結束前 SET ROWCOUNT 0。
  • ⚠️ SQL Server 2012+ 已棄用:SET ROWCOUNT 不再影響 DELETE/INSERT/UPDATE,新版請改用 OFFSET ... FETCH。

現代替代方案 (SQL Server 2012+)

CREATE PROCEDURE usp_PageResults_Modern
    @PageNumber INT,   -- 1-based
    @PageSize INT
AS
BEGIN
    SELECT e.*, d.Name AS DepartmentName
    FROM Employees e
    INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID
    ORDER BY e.EmployeeID
    OFFSET (@PageNumber - 1) * @PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY;
END

效能比較 (百萬筆測試)

結語

SET ROWCOUNT 分頁法在 SQL Server 2000/2005/2008/R2 時代是大資料量分頁的高效利器。維護舊系統時可繼續沿用;新專案請直接採用標準 OFFSET/FETCH,語法標準、優化器支援更完善。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案邏輯讀取CPU (ms)耗時 (ms)
傳統 NOT IN1,200,000+4501,200
SET ROWCOUNT~50,00080120
OFFSET/FETCH~50,00075110