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

Oracle 高效分頁查詢優化:從 ROWNUM 子查詢到 ROW_NUMBER() 分析函數的性能躍升實測

     編輯:Oracle 資料庫基礎

分頁痛點

Web 應用常需分頁顯示。早期做法:一次性查出所有行交由前端控件分頁,導致資料庫壓力大、網絡傳輸量大、用戶體驗差。

傳統 ROWNUM 方案(低效)

SELECT * FROM (
  SELECT a.*, ROWNUM rnum FROM (
    SELECT * FROM yz_bingrenyz
  ) a WHERE ROWNUM <= 5300
) WHERE rnum >= 5000;

原理:內層查出前 5300 行,外層丟棄前 5000 行。隨頁碼增大,掃描行數線性增長,性能急劇下降。

優化方案:ROW_NUMBER() 分析函數

SELECT * FROM (
  SELECT * FROM (
    SELECT t.*, ROW_NUMBER() OVER (ORDER BY NULL) AS row_number
    FROM yz_bingrenyz t
  ) p WHERE p.row_number > 5000
) q WHERE ROWNUM <= 30;
  • ROW_NUMBER() OVER (ORDER BY NULL) 為每行分配唯一序號,無排序開銷。
  • 外層先過濾 row_number > 5000,再取前 30 行,實現「精準定位 + 少量取數」。

實測對比(百萬級測試表)

方案耗時執行計劃特徵
ROWNUM 子查詢1.3 s全表掃描 + COUNT STOPKEY 後過濾
ROW_NUMBER()0.25 sWINDOW SORT + FILTER 提前裁剪

性能提升 5 倍以上,且隨頁碼增長優勢擴大。

工程落地建議

  • 封裝為 PL/SQL 存儲過程或中間層工具類(C# DbCommand 動態拼接表名、主鍵、頁碼、頁大小)。
  • 避免在存儲過程中使用動態 SQL 導致硬解析,優先使用綁定變量。
  • 若使用 Entity Framework,直接調用 Skip()/Take(),EF 會自動生成類似 ROW_NUMBER() 的高效 SQL。

總結

棄用「先取後丟」的 ROWNUM 子查詢,改用 ROW_NUMBER() 分析函數配合外層 ROWNUM 截斷,是 Oracle 高效分頁的標準最佳實踐。

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