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

Oracle SQL 調優實戰:30 個常用 Hint 完整指南

     編輯:Oracle 資料庫相關知識

前言

Oracle 優化器 (CBO) 在大多數情況下能自動產生最佳執行計畫,但在統計資訊不足、資料分佈傾斜、複雜連接等場景,DBA/開發人員需透過 Hint (提示) 強制指定存取路徑、連接順序或優化目標。本文整理 30 個實務常見 Hint,附語法、用途與範例,供快速查閱。

一、優化目標類

Hint用途範例
/*+ ALL_ROWS */以「最小化總資源消耗」為目標,適合批次/報表查詢SELECT /*+ ALL_ROWS */ emp_no FROM bempms WHERE emp_no='SCOTT';
/*+ FIRST_ROWS */以「最快回應第一筆資料」為目標,適合互動式畫面SELECT /*+ FIRST_ROWS */ emp_no FROM bempms WHERE emp_no='SCOTT';
/*+ CHOOSE */有統計資訊用 CBO,無則用 RBO (已棄用,僅相容舊版)SELECT /*+ CHOOSE */ emp_no FROM bempms WHERE emp_no='SCOTT';
/*+ RULE */強制使用規則基礎優化器 (RBO),Oracle 10g+ 已不建議使用SELECT /*+ RULE */ emp_no FROM bempms WHERE emp_no='SCOTT';

二、存取路徑類

Hint用途範例
/*+ FULL(table) */全表掃描SELECT /*+ FULL(a) */ emp_no FROM bempms a WHERE emp_no='SCOTT';
/*+ ROWID(table) */指定以 ROWID 存取SELECT /*+ ROWID(bempms) */ * FROM bempms WHERE rowid>='AAAAAAAAAAAAAA';
/*+ CLUSTER(table) */叢集掃描 (僅限叢集表)SELECT /*+ CLUSTER */ bempms.emp_no FROM bempms, bsdptms WHERE bempms.dpt_no=bsdptms.dpt_no;
/*+ INDEX(table index) */指定索引掃描SELECT /*+ INDEX(bempms sex_index) */ * FROM bempms WHERE sex='M';
/*+ INDEX_ASC(table index) */索引遞增掃描SELECT /*+ INDEX_ASC(bempms pk_bempms) */ * FROM bempms WHERE dpt_no='SCOTT';
/*+ INDEX_DESC(table index) */索引遞減掃描SELECT /*+ INDEX_DESC(bempms pk_bempms) */ * FROM bempms WHERE dpt_no='SCOTT';
/*+ INDEX_COMBINE(table index1, index2) */位圖索引布林組合SELECT /*+ INDEX_COMBINE(bempms sal_bmi hiredate_bmi) */ * FROM bempms WHERE sal<5000000 AND hiredate
/*+ INDEX_JOIN(table index1, index2) */索引連接存取 (避免回表)SELECT /*+ INDEX_JOIN(bempms sal_hmi hiredate_bmi) */ sal, hiredate FROM bempms WHERE sal<60000;
/*+ INDEX_FFS(table index) */快速全索引掃描 (替代全表掃描)SELECT /*+ INDEX_FFS(bempms in_empnam) */ * FROM bempms WHERE dpt_no='TEC305';
/*+ ADD_EQUAL(table index1, index2) */合併多個單欄索引掃描SELECT /*+ INDEX_FFS(bempms in_dptno, in_empno, in_sex) */ * FROM bempms WHERE emp_no='SCOTT' AND dpt_no='TDC306';

三、連接順序與方法類

Hint用途範例
/*+ ORDERED */依 FROM 子句順序連接SELECT /*+ ORDERED */ a.col1,b.col2 FROM table1 a,table2 b WHERE a.col1=b.col1;
/*+ LEADING(table) */指定驅動表 (建議搭配 ORDERED)SELECT /*+ LEADING(a) */ * FROM table1 a, table2 b WHERE a.id=b.id;
/*+ USE_NL(table) */巢狀迴圈連接 (指定內部表)SELECT /*+ ORDERED USE_NL(bempms) */ * FROM bsdptms, bempms WHERE bsdptms.dpt_no=bempms.dpt_no;
/*+ USE_MERGE(table) */排序合併連接SELECT /*+ USE_MERGE(bempms,bsdptms) */ * FROM bempms,bsdptms WHERE bempms.dpt_no=bsdptms.dpt_no;
/*+ USE_HASH(table) */雜湊連接SELECT /*+ USE_HASH(bempms,bsdptms) */ * FROM bempms,bsdptms WHERE bempms.dpt_no=bsdptms.dpt_no;
/*+ DRIVING_SITE(table) */強制在指定站點執行分散式查詢SELECT /*+ DRIVING_SITE(dept) */ * FROM bempms, dept@bsdptms WHERE bempms.dpt_no=dept.dpt_no;

四、查詢轉換與重寫類

Hint用途範例
/*+ USE_CONCAT */將 WHERE 中的 OR 條件轉為 UNION ALLSELECT /*+ USE_CONCAT */ * FROM bempms WHERE dpt_no='TDC506' AND sex='M';
/*+ NO_EXPAND */阻止 OR/IN-LIST 擴展為 UNION ALLSELECT /*+ NO_EXPAND */ * FROM bempms WHERE dpt_no='TDC506' AND sex='M';
/*+ REWRITE */啟用物化視圖重寫 (可指定視圖名)SELECT /*+ REWRITE(mv_sales) */ * FROM sales WHERE year=2023;
/*+ NO_REWRITE */禁止查詢重寫SELECT /*+ NO_REWRITE */ * FROM sales WHERE year=2023;
/*+ MERGE(view) */合併視圖查詢區塊SELECT /*+ MERGE(v) */ a.emp_no FROM bempms a, (SELECT dpt_no,AVG(sal) avg_sal FROM bempms GROUP BY dpt_no) v WHERE a.dpt_no=v.dpt_no AND a.sal>v.avg_sal;
/*+ NO_MERGE(view) */禁止視圖合併SELECT /*+ NO_MERGE(v) */ a.emp_no FROM bempms a, (SELECT dpt_no,AVG(sal) avg_sal FROM bempms GROUP BY dpt_no) v WHERE a.dpt_no=v.dpt_no AND a.sal>v.avg_sal;

五、快取與 DML 類

Hint用途範例
/*+ CACHE(table) */全表掃描時將區塊置於 LRU 熱端SELECT /*+ FULL(bempms) CACHE(bempms) */ emp_nam FROM bempms;
/*+ NOCACHE(table) */全表掃描時將區塊置於 LRU 冷端 (預設)SELECT /*+ FULL(bempms) NOCACHE(bempms) */ emp_nam FROM bempms;
/*+ APPEND */直接路徑插入 (High Water Mark 之後),加速大量載入INSERT /*+ APPEND */ INTO test1 SELECT * FROM test4;
/*+ NOAPPEND */停用並行模式,執行傳統插入INSERT /*+ NOAPPEND */ INTO test1 SELECT * FROM test4;

六、實務提醒

  1. Hint 僅為「建議」,優化器在語意衝突或版本限制下可能忽略;務必以 EXPLAIN PLAN 驗證實際執行計畫。
  2. 優先收集完整統計資訊 (DBMS_STATS.GATHER_TABLE_STATS)、建立適當索引、重寫 SQL,再考慮 Hint。
  3. 生產環境上線前,必須在測試環境進行效能基準測試 (Benchmark)。
  4. Oracle 12c+ 引入 /*+ OPT_PARAM('_optimizer_adaptive_plans' 'false') */ 等內部參數 Hint,需極度謹慎使用。

結語

熟練掌握上述 Hint,能在優化器「選錯路」時快速干預。但請記住:Hint 是最後手段,而非首選方案。持續優化統計資訊、索引設計與 SQL 寫法,才是穩定效能的根本之道。

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