Oracle 提供三種優化器模式:RULE(規則基礎)、COST/CHOOSE(成本基礎)。正確選擇與統計資訊管理,直接決定 SQL 執行計畫品質。本文深度解析三模式運作機制、OPTIMIZER_MODE 參數、統計資訊策略、存取路徑選擇、共享游標條件,助您事半功倍。
| 模式 | 觸發條件 | 特性 | 適用版本/場景 |
|---|---|---|---|
| RULE (RBO) | OPTIMIZER_MODE=RULE 或 Hint /*+ RULE */ | 固定規則排名(索引 > 全表掃描),不參考統計資訊 | Oracle 7/8 早期應用、極簡查詢、統計資訊缺失時的兜底 |
| COST (CBO) | OPTIMIZER_MODE=COST / ALL_ROWS / FIRST_ROWS_n,且物件有統計資訊 | 根據統計資訊估算成本(CPU、I/O、記憶體),選擇最低成本路徑 | 現代標準,所有生產環境應使用 |
| CHOOSE | OPTIMIZER_MODE=CHOOSE(預設,9i 以前) | 若物件有統計資訊 → CBO;無統計資訊 → RBO | 已淘汰(10g+ 移除),易導致非預期全表掃描 |
-- 1. 執行個體層級 (init.ora / spfile)
OPTIMIZER_MODE = ALL_ROWS -- 全表最佳吞吐量(批次、報表)
OPTIMIZER_MODE = FIRST_ROWS_10 -- 前 10 列最快回應(OLTP、分頁)
-- 2. Session 層級
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS_1;
-- 3. Statement 層級 (Hint)
SELECT /*+ ALL_ROWS */ * FROM big_table;
SELECT /*+ FIRST_ROWS(10) */ * FROM orders WHERE cust_id = :1;
建議:實例層級設ALL_ROWS,OLTP 關鍵查詢用FIRST_ROWS_nHint 微調。嚴禁使用 CHOOSE。
CBO 依賴 DBMS_STATS 收集的統計資訊:
DBMS_STATS.GATHER_SYSTEM_STATS)。-- 標準收集作業(排程每日/每週執行)
BEGIN
DBMS_STATS.GATHER_DATABASE_STATS(
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
cascade => TRUE,
degree => DBMS_STATS.AUTO_DEGREE,
options => 'GATHER AUTO' -- 11g+ 智慧收集
);
END;
/
關鍵:STALE_PERCENT(預設 10%)超過即標記過期,自動收集作業(AUTO_TASK)會處理。大表建議啟用增量統計(INCREMENTAL=TRUE + 分區表)。
| 路徑 | 機制 | 觸發條件 | 優化手段 |
|---|---|---|---|
| 全表掃描 (FTS) | 多區塊讀取 (db_file_multiblock_read_count),掃描 High Water Mark 以下所有區塊 | 無索引、選擇率高(> 5-10%)、平行查詢、小表 | 分區裁剪、平行度、Exadata Smart Scan |
| 索引存取 | B-tree 索引範圍掃描 → ROWID → TABLE ACCESS BY INDEX ROWID | 選擇率低、高選擇性欄位、索引覆蓋查詢 | 建立複合索引、包含欄位 (INCLUDE)、索引壓縮、函數索引 |
ROWID 含資料物理位置(物件號、檔案號、區塊號、列號),索引即「鍵值 → ROWID」映射。
相同 SQL 文字(字元級完全相符,含大小寫、空白、換行)可共用解析樹與執行計畫,減少 Hard Parse。
OPTIMIZER_MODE、NLS 參數、_optimizer_* 隱藏參數等一致。PreparedStatement / bind variables),避免字面值導致 Hard Parse 暴增。CURSOR_SHARING = FORCE 僅作過渡方案,可能產生次優計畫,長期應修正程式碼。SHARED_POOL_SIZE / RESULT_CACHE 容納更多游標。LAST_ANALYZED 近期)STATUS=VALID、VISIBLE)WHERE TO_CHAR(date_col) = '2024' → 失效)OPTIMIZER_MODE 非 CHOOSE / RULEADAPTIVE_CURSOR_SHARING 緩解)掌握優化器模式、統計資訊、存取路徑、共享游標四大支柱,即可從根源解決 80% 的 SQL 效能問題,實現「事半功倍」。