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

Oracle Hint 完整指南:32 類優化提示語法、分類與實戰案例

     編輯:Oracle 資料庫相關知識

Hint 是 Oracle 提供給開發者干預優化器決策的機制,可控制優化模式、存取路徑、連接順序、並行度等。本文系統整理 32 類常用 Hint,附帶語法、參數說明與實戰範例。

Hint 作用範圍

  • 影響優化器選擇:RBO vs CBO、ALL_ROWS vs FIRST_ROWS
  • 表存取路徑:全表掃描、索引掃描、ROWID 存取
  • 表連接:連接順序、連接方法、驅動站點
  • 並行執行:Parallel Degree、PDML 啟用
  • 查詢轉換:OR 展開、視圖合併、子查詢展開

語法格式

{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
-- 或
{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...

語法錯誤時 Oracle 靜默忽略,不報錯。

32 類核心 Hint 分類速查

優化目標類

Hint用途範例
ALL_ROWS吞吐量優先SELECT /*+ALL_ROWS*/ * FROM emp WHERE deptno=10;
FIRST_ROWS回應時間優先SELECT /*+FIRST_ROWS*/ * FROM emp WHERE deptno=10;
CHOOSE有統計資訊用 CBO,否則 RBOSELECT /*+CHOOSE*/ * FROM emp;
RULE強制規則基礎優化SELECT /*+RULE*/ * FROM emp;

存取路徑類

Hint用途範例
FULL(table)全表掃描SELECT /*+FULL(e)*/ * FROM emp e;
ROWID(table)ROWID 存取SELECT /*+ROWID(emp)*/ * FROM emp WHERE ROWID>='...';
CLUSTER(table)叢集掃描SELECT /*+CLUSTER*/ * FROM emp, dept WHERE ...;
INDEX(table index)指定索引掃描SELECT /*+INDEX(emp emp_idx)*/ * FROM emp WHERE deptno=10;
INDEX_ASC/DESC索引升/降序掃描SELECT /*+INDEX_DESC(emp pk_emp)*/ * FROM emp;
INDEX_COMBINE位圖索引合併SELECT /*+INDEX_COMBINE(emp idx1 idx2)*/ * FROM emp;
INDEX_JOIN索引連接存取SELECT /*+INDEX_JOIN(emp idx1 idx2)*/ sal, hiredate FROM emp;
INDEX_FFS快速全索引掃描SELECT /*+INDEX_FFS(emp idx_name)*/ * FROM emp;
NO_INDEX禁止使用指定索引SELECT /*+NO_INDEX(emp idx_sal idx_dept)*/ * FROM emp;

連接順序與方法類

Hint用途範例
ORDERED依 FROM 子句順序連接SELECT /*+ORDERED*/ * FROM a,b,c WHERE a.id=b.id AND b.id=c.id;
LEADING(table)指定驅動表SELECT /*+LEADING(a)*/ * FROM a,b WHERE a.id=b.id;
USE_NL(table)巢狀迴圈連接SELECT /*+USE_NL(b)*/ * FROM a,b WHERE a.id=b.id;
USE_MERGE(table)排序合併連接SELECT /*+USE_MERGE(a,b)*/ * FROM a,b WHERE a.id=b.id;
USE_HASH(table)雜湊連接SELECT /*+USE_HASH(a,b)*/ * FROM a,b WHERE a.id=b.id;
DRIVING_SITE(table)強制遠端執行SELECT /*+DRIVING_SITE(d)*/ * FROM emp, dept@remote d WHERE ...;

其他實用 Hint

Hint用途
CACHE/NOCACHE全表掃描時控制緩衝區 LRU 位置
APPEND/NOAPPEND直接路徑插入/傳統插入
REWRITE/NOREWRITE啟用/停用查詢重寫
MERGE/NO_MERGE視圖合併/不合併
UNION/NO_EXPANDOR 轉 UNION ALL / 禁止展開
PARALLEL(table, degree)指定並行度

實戰案例:PDML 並行插入失效排查

-- 錯誤寫法:未啟用 PDML,並行提示無效
INSERT /*+parallel(a)*/ INTO target SELECT /*+parallel(a)*/ * FROM source a;

-- 正確寫法:Session 層面啟用 PDML
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+parallel(target,4)*/ INTO target SELECT /*+parallel(a)*/ * FROM source a;

關鍵點:Oracle 預設不開啟 PDML,DML 語句必須 Session 級啟用;並行非萬能,OLTP 環境需謹慎使用。

複雜實戰:NOT EXISTS 子查詢禁用索引

SELECT COUNT(*) FROM wid_serv_prod_mon_1100 a
WHERE a.acct_month = 201010
  AND NOT EXISTS (
    SELECT /*+NO_INDEX(b IDX_W_CDR_MON_SERV_ID_1100)*/ 1
    FROM wid_cdr_mon_1100 b
    WHERE b.acct_month = 201010
      AND b.ANA_EVENT_TYPE_4 IN (...)
      AND a.serv_id = b.serv_id
  );

善用 Hint 需結合執行計畫分析,盲目添加反而適得其反。

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