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

SQL Server 分頁查詢:TOP 嵌套 vs ROW_NUMBER() 效能實測

     編輯:關於SqlServer

兩種經典分頁寫法

1. TOP 雙重嵌套(SQL 2000/2005 通用)

SELECT TOP 10 *
FROM TCCLine.dbo.CLine_CommonImage
WHERE id NOT IN (
    SELECT TOP 40 id
    FROM TCCLine.dbo.CLine_CommonImage
    ORDER BY id
)
ORDER BY id;

邏輯:跳過前 40 筆(第 5 頁,頁大小 10),再取 10 筆。

2. ROW_NUMBER() 窗口函數(SQL 2005+)

SELECT TOP 10 numComImg.*
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY id ASC) AS rownumber, *
    FROM (SELECT * FROM TCCLine.dbo.CLine_CommonImage) AS comImg
) AS numComImg
WHERE rownumber > 40;

執行計畫對比

執行計畫成本比較

  • TOP 嵌套:兩次 Clustered Index Scan,總成本 72%。
  • ROW_NUMBER():單次掃描 + 窗口運算,總成本 28%。

統計時間實測

SET STATISTICS TIME ON;
-- 執行上述兩條查詢

ROW_NUMBER 耗時

TOP 嵌套 耗時

結論:ROW_NUMBER() CPU 與 Elapsed 時間均顯著低於 TOP 雙重掃描,隨資料量增長優勢擴大。

補充:現代最佳寫法(SQL 2012+)

SELECT *
FROM TCCLine.dbo.CLine_CommonImage
ORDER BY id
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY;
  • 語法最簡潔,最佳化器內部同樣轉換為窗口函數,效能等同 ROW_NUMBER()。
  • 支援變數參數化,適合預存程序。

避坑指南

  1. 分頁欄位必須唯一(主鍵或唯一索引),否則翻頁資料可能重複/遺漏。
  2. 深分頁(如第 10 萬頁)仍會掃描大量前置列;極大資料集建議採用「鍵值游標法」(記住上一頁最大 ID,下頁 WHERE id > @lastId)。
  3. 避免在 CTE/子查詢中使用 SELECT *,僅選需要欄位減少 I/O。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved