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

Oracle SQL 優化 30 大 Hint 實戰指南:從全表掃描到連接策略控制

     編輯:關於SqlServer

前言:Hint 的雙刃劍

Oracle Hint (`/*+ ... */`) 是指導優化器生成特定執行計畫的指令。慎用原則:統計資訊完整、優化器模式正確時,優化器通常比人工更聰明。Hint 適用於:統計資訊缺失、複雜查詢優化器迷路、測試不同計畫、緊急繞過 Bug。

優化目標導向 Hint

Hint目標適用場景
/*+ ALL_ROWS */最佳吞吐量 (總成本最低)批次處理、報表、資料倉儲
/*+ FIRST_ROWS(n) */最佳響應時間 (前 n 行最快)互動式應用、分頁查詢、Web 頁面
/*+ CHOOSE */有統計用 CBO,無統計用 RBO遷移期混合環境 (舊版本)
/*+ RULE */強制規則基礎優化 (RBO)極舊系統相容,現代版本已棄用

存取路徑控制 (單表)

Hint行為範例
/*+ FULL(t) */全表掃描`SELECT /*+ FULL(emp) */ * FROM emp`
/*+ ROWID(t) */指定 ROWID 存取`SELECT /*+ ROWID(emp) */ * FROM emp WHERE rowid > '...'`
/*+ CLUSTER(t) */叢集掃描 (僅叢集表)`SELECT /*+ CLUSTER */ * FROM emp, dept WHERE ...`
/*+ INDEX(t idx) */指定索引範圍掃描`SELECT /*+ INDEX(emp emp_sex_idx) */ * FROM emp WHERE sex='M'`
/*+ INDEX_ASC(t idx) */索引遞增掃描`SELECT /*+ INDEX_ASC(emp pk_emp) */ * FROM emp WHERE deptno=10`
/*+ INDEX_DESC(t idx) */索引遞減掃描`SELECT /*+ INDEX_DESC(emp pk_emp) */ * FROM emp WHERE deptno=10`
/*+ INDEX_FFS(t idx) */快速全索引掃描 (代替全表掃描)`SELECT /*+ INDEX_FFS(emp emp_name_idx) */ * FROM emp WHERE deptno=20`
/*+ INDEX_COMBINE(t idx1 idx2) */位圖索引合併 (AND/OR)`SELECT /*+ INDEX_COMBINE(emp sal_bmi hiredate_bmi) */ * FROM emp WHERE sal<5000 AND hiredate
/*+ INDEX_JOIN(t idx1 idx2) */索引連接 (不回表)`SELECT /*+ INDEX_JOIN(emp sal_idx hd_idx) */ sal, hiredate FROM emp WHERE sal<60000`
/*+ AND_EQUAL(t idx1 idx2) */合併多個單欄索引 (舊語法)`SELECT /*+ AND_EQUAL(emp idx_dpt idx_emp idx_sex) */ * FROM emp WHERE empno=... AND deptno=...`

查詢轉換與重寫控制

Hint行為說明
/*+ USE_CONCAT */將 OR 條件轉為 UNION ALL避免全表掃描,各分支可用各自索引
/*+ NO_EXPAND */阻止 OR/IN-LIST 展開防止計畫膨脹
/*+ REWRITE(v) */啟用物化視圖重寫可指定視圖名
/*+ NO_REWRITE */禁止查詢重寫排查重寫錯誤
/*+ MERGE(v) */強制視圖合併 (View Merging)將視圖定義合併至主查詢,開啟更多優化機會
/*+ NO_MERGE(v) */禁止視圖合併保護視圖邊界,或避免錯誤合併

多表連接策略控制

Hint連接方式適用條件
/*+ ORDERED */依 FROM 子句順序連接開發者確定最佳驅動順序時
/*+ LEADING(t) */指定驅動表 (建議替代 ORDERED)更靈活,只固定第一張表
/*+ USE_NL(t) */Nested Loops (指定表為內部表)驅動集小、內部表有高選擇性索引
/*+ USE_MERGE(t) */Sort Merge Join雙邊大集合、已排序或無合適索引
/*+ USE_HASH(t) */Hash Join大表連接大表、等值連接、記憶體充足
/*+ DRIVING_SITE(t) */強制在指定遠端站點執行分散式查詢,減少網路傳輸

並行與快取控制

Hint行為備註
/*+ CACHE(t) */全表掃描時將區塊置於 LRU 熱端小熱表,避免被淘汰
/*+ NOCACHE(t) */全表掃描區塊置於 LRU 冷端 (預設)大表掃描,保護熱資料
/*+ APPEND */直接路徑插入 (High Water Mark 以上)大量載入,繞過 Undo/Redo 部分邏輯,速度極快
/*+ NOAPPEND */傳統插入 (關閉並行模式)需觸發 Trigger/Constraint 時
/*+ PARALLEL(t, 4) */指定並行度 (常用但非列表內)大表全掃/建索引/大量 DML

實戰組合範例


-- 場景:大表連接,指定驅動表、Hash Join、並行 4,目標吞吐量
SELECT /*+ ALL_ROWS LEADING(orders) USE_HASH(customers) PARALLEL(orders, 4) PARALLEL(customers, 4) */
       o.order_id, c.cust_name, o.order_total
FROM   orders o, customers c
WHERE  o.cust_id = c.cust_id
AND    o.order_date > SYSDATE - 30;

-- 場景:分頁查詢,優化首頁響應,強制索引範圍掃描
SELECT /*+ FIRST_ROWS(20) INDEX(orders ord_dt_idx) */
       order_id, order_date
FROM   orders
WHERE  order_date > SYSDATE - 7
ORDER BY order_date DESC
FETCH FIRST 20 ROWS ONLY; -- 12c+ 語法

避坑指南

  1. 綁定變量窺探:Hint 固定計畫可能導致參數嗅探問題,考慮 `OPT_PARAM('_optim_peek_user_binds', 'false')` 或 `ACS` (適應性游標共享)。
  2. 統計資訊為本:90% 的效能問題源於統計資訊過時/缺失。優先 `DBMS_STATS.GATHER_TABLE_STATS`,再考慮 Hint。
  3. 版本演進:11g+ 引入 SQL Plan Management (SPM),建議用 SQL Plan Baseline 固定計畫,比 Hint 更安全、可演進。
  4. 註解語法:Hint 必須緊跟 `SELECT/INSERT/UPDATE/DELETE` 關鍵字後,格式 `/*+ HINT */`,大小寫不敏感。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved