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

SQL Server 分頁預存程序演進:從雙重 TOP 到 ROW_NUMBER()、OFFSET/FETCH 的效能與寫法比較

     編輯:關於SqlServer

UI 分頁兩大路徑:

路徑SQL 複雜度程式碼量設計時支援效能
前端分頁 (撈全表)簡單少完整資料量大時極差
資料庫分頁 (撈單頁)視寫法多部分良好,與 SQL 寫法相關

本文聚焦資料庫分頁,以 Production.Product (ProductID, Name) 為例。

分頁參數

  • PageIndex:頁碼 (0-based)
  • PageSize:頁大小
  • RecordCount:總筆數
  • PageCount:總頁數

經典雙重 TOP 寫法 (SQL 2000 相容)

-- 取第 @PageIndex 頁,每頁 @PageSize 筆
SELECT TOP (@PageSize) *
FROM (
    SELECT TOP ((@PageIndex + 1) * @PageSize) *
    FROM Production.Product
    ORDER BY ProductID
) AS t
ORDER BY ProductID DESC
  • 內層取前 N 頁,外層倒序取最後一頁再正序。
  • 需唯一排序鍵 (ProductID) 保證確定性。
  • 大頁碼時內層 TOP 掃描量大,效能下降。

現代寫法演進

版本語法優勢
SQL 2005+ROW_NUMBER() OVER (ORDER BY ProductID) + CTE 篩選 rn BETWEEN ...單掃描、可任意頁碼、支援複雜排序
SQL 2012+OFFSET @PageIndex * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY標準 ANSI、最簡潔、最佳化器原生支援

效能建議

  • 確保排序欄位有索引(叢集索引最佳)。
  • 大資料量避免 OFFSET 深分頁(掃描前 N 列),改用鍵值游標分頁 (WHERE ProductID > @last_seen_id ORDER BY ProductID LIMIT @PageSize)。
  • 總筆數 COUNT(*) 另查,或使用近似值 (sys.dm_db_partition_stats)。

總結

從雙重 TOP → ROW_NUMBER() → OFFSET/FETCH,分頁寫法隨版本演進越來越簡潔高效。核心原則:單掃描、索引支援排序、避免深分頁掃描。舊版本維護雙重 TOP 仍可接受,新專案優先 OFFSET/FETCH 或鍵值游標。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved