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

SQL Server 分頁查詢三大方案深度對比:NOT IN vs ID 範圍 vs ROW_NUMBER

     編輯:關於SqlServer

測試表結構

CREATE TABLE table1 (id INT PRIMARY KEY, ...);

方案一:NOT IN + 子查詢(經典但低效)

SELECT TOP @PageSize * 
FROM table1 
WHERE id NOT IN (
    SELECT TOP @PageSize * (@PageNum - 1) id 
    FROM table1 ORDER BY id
)
ORDER BY id;

缺點:NOT IN 子查詢每頁重掃;含 NULL 時語義陷阱;大偏移量效能急劇下降。

方案二:ID > 最大值 游標式(高效、需連續/單調 ID)

-- 正序
SELECT TOP @PageSize * 
FROM table1 
WHERE id > (
    SELECT ISNULL(MAX(id), 0) 
    FROM (
        SELECT TOP @PageSize * (@PageNum - 1) id 
        FROM table1 ORDER BY id
    ) t
)
ORDER BY id;

-- 倒序(最新優先,常見於論壇/動態)
SELECT TOP @PageSize * 
FROM table1 
WHERE id <= (
    SELECT ISNULL(MIN(id), (SELECT MAX(id) FROM table1))
    FROM (
        SELECT TOP @PageSize * (@PageNum - 1) id 
        FROM table1 ORDER BY id DESC
    ) t
)
ORDER BY id DESC;

優點:索引查找定位起始點,僅掃描一頁資料,**效能最佳**。
前提:ID 唯一、單調遞增(或遞減)、無大量刪除導致斷層過大。

方案三:ROW_NUMBER() 視窗函數(通用標準,SQL 2005+)

SELECT TOP @PageSize * 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY id) AS rn, * 
    FROM table1
) t
WHERE rn > @PageSize * (@PageNum - 1);

優點:無 ID 連續性要求、支援任意排序、ANSI SQL 標準。
缺點:大偏移量需掃描並排序前 N 行,**效能最差**(全表排序 + 視窗計算)。

效能排序與選型建議

方案效能適用場景備註
ID 範圍 (方案二)⭐⭐⭐⭐⭐單調 ID、高頻翻頁、大資料量需動態拼接 SQL
NOT IN (方案一)⭐⭐⭐小資料量、簡單原型易踩 NULL 坑
ROW_NUMBER (方案三)⭐⭐無單調鍵、複雜排序、通用框架大偏移考慮 Keyset 分頁

進階:Keyset Pagination (游標分頁) — 現代最佳實踐

-- 首頁
SELECT TOP 20 * FROM table1 ORDER BY id DESC;

-- 後續頁(記住上一頁最後一筆 id = @last_id)
SELECT TOP 20 * FROM table1 WHERE id < @last_id ORDER BY id DESC;

無偏移量掃描、極致效能、適合無限滾動/APP 分頁。缺點:不支援跳頁、需客戶端記錄游標。

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