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

Oracle Hint 完整指南:30 個常用提示語法、參數與實戰範例

     編輯:Oracle 資料庫基礎

什麼是 Hint?

Hint(提示)是嵌入在 SQL 註解中的特殊指令,用於引導最佳化器選擇特定執行計畫。語法格式:/*+ HINT_NAME([parameters]) */。善用 Hint 可在統計資訊不足、最佳化器判斷失誤時強制指定存取路徑、聯結順序或並行度。

最佳化模式類

Hint說明範例
ALL_ROWS以成本為基礎,追求最佳吞吐量(全表掃描傾向)SELECT /*+ ALL_ROWS */ * FROM emp WHERE deptno=10;
FIRST_ROWS(n)以成本為基礎,追求前 n 列最快回應時間SELECT /*+ FIRST_ROWS(10) */ * FROM emp ORDER BY hiredate;
CHOOSE有統計資訊用 CBO,無則用 RBO(已棄用)SELECT /*+ CHOOSE */ * FROM emp;
RULE強制使用規則基礎最佳化(已棄用)SELECT /*+ RULE */ * FROM emp;

存取路徑類

Hint說明範例
FULL(table)全表掃描SELECT /*+ FULL(e) */ * FROM emp e;
ROWID(table)指定 ROWID 存取SELECT /*+ ROWID(e) */ * FROM emp e WHERE ROWID='AAA...';
CLUSTER(table)叢集掃描(僅叢集表)SELECT /*+ CLUSTER(e) */ * FROM emp e, dept d WHERE e.deptno=d.deptno;
INDEX(table [index])索引範圍掃描SELECT /*+ INDEX(e emp_idx) */ * FROM emp e WHERE deptno=10;
INDEX_ASC / INDEX_DESC索引升/降序掃描SELECT /*+ INDEX_DESC(e pk_emp) */ * FROM emp e WHERE empno>100;
INDEX_COMBINE位圖索引布林組合SELECT /*+ INDEX_COMBINE(e idx1 idx2) */ * FROM emp e WHERE sal<5000 AND hiredate>...;
INDEX_JOIN索引聯結(不回表)SELECT /*+ INDEX_JOIN(e idx_sal idx_hire) */ sal, hiredate FROM emp e WHERE sal<60000;
INDEX_FFS(table index)快速全索引掃描SELECT /*+ INDEX_FFS(e emp_name_idx) */ * FROM emp e WHERE deptno=20;
INDEX_SS / INDEX_SS_ASC / INDEX_SS_DESC索引跳躍掃描SELECT /*+ INDEX_SS(e comp_idx) */ * FROM emp e WHERE deptno=10;

聯結方法類

Hint說明範例
USE_NL(table)巢狀迴圈聯結,指定表為內部表SELECT /*+ ORDERED USE_NL(e) */ * FROM dept d, emp e WHERE d.deptno=e.deptno;
USE_MERGE(table)排序合併聯結SELECT /*+ USE_MERGE(e,d) */ * FROM emp e, dept d WHERE e.deptno=d.deptno;
USE_HASH(table)雜湊聯結SELECT /*+ USE_HASH(e,d) */ * FROM emp e, dept d WHERE e.deptno=d.deptno;

聯結順序與驅動站點類

Hint說明範例
ORDERED依 FROM 子句順序聯結SELECT /*+ ORDERED */ * FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
LEADING(table)指定第一個驅動表SELECT /*+ LEADING(d) */ * FROM dept d, emp e WHERE d.deptno=e.deptno;
DRIVING_SITE(table)強制在指定站點執行(分散式查詢)SELECT /*+ DRIVING_SITE(d) */ * FROM emp e, dept@remote d WHERE e.deptno=d.deptno;

查詢轉換與重寫類

Hint說明範例
USE_CONCAT將 OR/IN-LIST 展開為 UNION ALLSELECT /*+ USE_CONCAT */ * FROM emp WHERE deptno=10 OR deptno=20;
NO_EXPAND禁止 OR/IN-LIST 展開SELECT /*+ NO_EXPAND */ * FROM emp WHERE deptno IN (10,20,30);
REWRITE / NO_REWRITE啟用/停用物化視圖重寫SELECT /*+ REWRITE(mv_sales) */ * FROM sales WHERE year=2023;
MERGE / NO_MERGE合併/不合併視圖/子查詢SELECT /*+ MERGE(v) */ * FROM emp e, (SELECT deptno, AVG(sal) avg_sal FROM emp GROUP BY deptno) v WHERE e.deptno=v.deptno AND e.sal>v.avg_sal;
STAR_TRANSFORMATION星狀轉換(資料倉儲)SELECT /*+ STAR_TRANSFORMATION */ * FROM fact f, dim1 d1, dim2 d2 WHERE f.d1_key=d1.key AND f.d2_key=d2.key;

並行與資源控制類

Hint說明範例
PARALLEL(table n)指定並行度SELECT /*+ PARALLEL(e,4) */ * FROM emp e;
NOPARALLEL禁止並行SELECT /*+ NOPARALLEL */ * FROM emp;
APPEND / NOAPPEND直接路徑插入/常規插入INSERT /*+ APPEND */ INTO target SELECT * FROM source;
CACHE / NOCACHE全掃描時置於/移出 LRU 熱端SELECT /*+ FULL(e) CACHE(e) */ * FROM emp e;

其他實用 Hint

  • PUSH_PRED / NO_PUSH_PRED:謂詞下推至視圖/子查詢
  • PUSH_SUBQ / NO_PUSH_SUBQ:子查詢提前/延後執行
  • QB_NAME:為查詢區塊命名,配合 @qb_name 精準指定 Hint 作用範圍
  • OPT_PARAM('_param_name' 'value'):會話層級暫時調整隱藏參數

最佳實務建議

  1. 優先收集統計資訊:DBMS_STATS.GATHER_TABLE_STATS 解決 90% 執行計畫問題,Hint 應為最後手段。
  2. 使用 QB_NAME 精準控制:避免 Hint 作用於錯誤查詢區塊(特別是視圖、CTE、子查詢巢狀)。
  3. 測試驗證:以 EXPLAIN PLAN、DBMS_XPLAN.DISPLAY_CURSOR 對比 Hint 前後計畫與實際執行時間。
  4. 文件化理由:在程式碼註解說明為何需 Hint、對應版本、預期移除條件(如統計資訊修正後)。

結語

Hint 是雙面刃:用得好可瞬間解決效能危機,濫用則會隨版本升級、資料分佈變化而失效甚至產生負面影響。建立「統計資訊優先、Hint 輔助、持續監控」的調優文化,才是長久之計。

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