首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 三大分頁寫法效能對比

     編輯:MySQL 資料庫相關知識

場景假設

  • 頁碼 @currentpage,每頁筆數 @pagesize
  • 主鍵 id 遞增唯一

寫法一:TOP + NOT IN(最經典、效能最差)

SELECT TOP @pagesize id, email, qq, wechat, phone, phone1
FROM contact
WHERE id NOT IN (
    SELECT TOP (@pagesize * (@currentpage - 1)) id 
    FROM contact ORDER BY id ASC
)
ORDER BY id ASC;

缺點:NOT IN 子查詢隨頁碼增大掃描量線性增長,深分頁極慢;不支援複合主鍵。

寫法二:TOP + MAX(需唯一排序欄位)

SELECT TOP @pagesize *
FROM contact
WHERE id > (
    SELECT MAX(id) FROM (
        SELECT TOP (@pagesize * (@currentpage - 1)) id 
        FROM contact ORDER BY id ASC
    ) t
)
ORDER BY id ASC;

缺點:排序欄位必須唯一,非唯一欄位會漏資料或重複。

寫法三:ROW_NUMBER() 窗口函數(SQL Server 2005+ 標準寫法)

SELECT * FROM (
    SELECT TOP (@pagesize * @currentpage) 
        ROW_NUMBER() OVER (ORDER BY id ASC) AS rn, *
    FROM contact
) t
WHERE rn > @pagesize * (@currentpage - 1);

優點:支援任意排序、非唯一欄位、複合排序,執行計劃穩定。

效能對比總結

寫法適用版本深分頁效能支援非唯一排序支援複合主鍵
TOP + NOT IN2000+差(O(N²))是否
TOP + MAX2000+中否否
ROW_NUMBER2005+優(單掃描)是是

Oracle 分頁參考

SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM aos_rms_user ORDER BY id
    ) a WHERE ROWNUM <= :maxRow
) WHERE rn >= :minRow;

現代最佳實踐

  • SQL Server 2012+ 直接用 OFFSET @offset ROWS FETCH NEXT @pagesize ROWS ONLY
  • 超大資料量(百萬+)深分頁改用游標分頁:WHERE id > @lastId ORDER BY id LIMIT @pagesize
  • 配合索引覆蓋查詢避免回表
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved