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

Oracle ROWNUM 分頁查詢陷阱:為何 ORDER BY 後 ROWNUM 失效與正確子查詢寫法

     編輯:Oracle 資料庫基礎

常見錯誤寫法

SELECT emp_no FROM emp 
WHERE ROWNUM < 10 
ORDER BY emp_no;

失效原因

  1. Oracle 先執行 WHERE 過濾 (含 ROWNUM),取得前 N 筆原始順序資料
  2. 再對結果集執行 ORDER BY 排序
  3. 結果:非排序後的前 N 筆,而是排序前的前 N 筆再排序

ROWNUM 是在資料擷取階段即時產生的偽欄位,非儲存值。

正確寫法:子查詢先排序再過濾

SELECT emp_no FROM (
  SELECT emp_no FROM emp ORDER BY emp_no
) WHERE ROWNUM < 10;
  • 內層查詢:完整排序產生有序結果集
  • 外層查詢:對已排序結果套用 ROWNUM 過濾
  • 獲得:真正排序後的前 N 筆

進階分頁查詢 (12c+ 標準語法)

-- Offset/Fetch (ANSI SQL 標準)
SELECT emp_no FROM emp 
ORDER BY emp_no 
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;

-- 12c 前通用寫法 (支援任意頁)
SELECT * FROM (
  SELECT a.*, ROWNUM rn FROM (
    SELECT emp_no FROM emp ORDER BY emp_no
  ) a WHERE ROWNUM <= :end_row
) WHERE rn >= :start_row;

ROWNUM 關鍵特性總結

效能提示

  • 大資料量分頁:確保 ORDER BY 欄位有索引,避免全表排序
  • 深分頁 (OFFSET 100000) 效能差,改用 Keyset Pagination:WHERE id > :last_id ORDER BY id FETCH NEXT 10
  • 統計資訊準確有助優化器選擇最佳排序方案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性說明
賦值時機資料源擷取時,WHERE 過濾前
值的範圍從 1 開始遞增
WHERE ROWNUM = 1有效 (首筆)
WHERE ROWNUM > 1永無結果 (首筆被過濾,後續永無機會變 1)
WHERE ROWNUM BETWEEN 5 AND 10無效,同理