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

Oracle 優化器原理深度解析:RBO vs CBO、四大模式與統計資訊管理

     編輯:Oracle 資料庫相關知識

核心架構:Optimizer (優化器)

Oracle 優化器負責將 SQL 轉換為執行計畫。歷經兩代演進:

代別名稱決策依據狀態
第一代RBO (Rule-Based Optimizer)固定規則集 (索引存在→用索引、全表掃描排序→用索引...)**10g 移除**,僅相容性保留
第二代CBO (Cost-Based Optimizer)統計資訊 (表/索引/欄位/系統) + CPU/IO 成本模型**唯一現代優化器** (10g+ 強制)

優化器模式參數 OPTIMIZER_MODE

模式值行為適用場景
RULE強制 RBO (已廢棄)極舊系統相容
CHOOSE有統計→CBO,無統計→RBO (9i 預設,**10g 移除**)9i 過渡期
FIRST_ROWSCBO,優化**首批行回應時間** (OLTP 分頁)互動式查詢、Web 分頁
FIRST_ROWS_nCBO,優化前 n 行 (n=1,10,100,1000)精細控制首屏速度
ALL_ROWSCBO,優化**總吞吐量/總成本最小** (預設 10g+)批次報表、資料倉庫、ETL

三層控制優化器行為

  1. Instance 級:ALTER SYSTEM SET OPTIMIZER_MODE=ALL_ROWS SCOPE=BOTH;
  2. Session 級:ALTER SESSION SET OPTIMIZER_MODE=FIRST_ROWS_10;
  3. Statement 級 (Hint):
    
    SELECT /*+ FIRST_ROWS(10) */ * FROM orders WHERE cust_id = :1;
    SELECT /*+ ALL_ROWS */ * FROM big_table;
    SELECT /*+ RULE */ * FROM legacy_table;  -- 僅 9i- 有效
            

統計資訊:CBO 的生命線

**統計過舊/缺失 = CBO 盲目亂猜 = 執行計畫災難**

收集統計標準流程


-- 1. 表級 (含索引、欄位直方圖)
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA', 'TABLE_NAME', METHOD_OPT=>'FOR ALL COLUMNS SIZE AUTO');

-- 2. Schema 級
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCHEMA', OPTIONS=>'GATHER AUTO');

-- 3. 自動任務 (10g+ 預設啟用,維護窗口每晚執行)
SELECT * FROM DBA_AUTOTASK_CLIENT WHERE CLIENT_NAME = 'auto optimizer stats collection';

自動化腳本:批量產生 ANALYZE (舊版相容) / DBMS_STATS (現代)


-- 現代版:產生 DBMS_STATS 呼叫腳本
SET PAGES 0 FEED OFF HEAD OFF
SPOOL gather_stats.sql
SELECT 'EXEC DBMS_STATS.GATHER_TABLE_STATS('''||owner||''','''||table_name||''', METHOD_OPT=>''FOR ALL COLUMNS SIZE AUTO'');'
FROM dba_tables WHERE owner = 'MY_SCHEMA';
SPOOL OFF
@gather_stats.sql

統計失效常見徵兆與對策

徵兆可能原因對策
突然走全表掃描統計顯示表很小 (實際大)、或索引統計缺失重收統計、檢查 NUM_ROWS vs 實際
索引不被使用欄位直方圖缺失導致選擇度錯估、或 CLUSTERING_FACTOR 惡化收集直方圖 SIZE SKEWONLY、重建索引
執行計畫震盪統計收集頻率過高/過低、Bind Variable Peeking鎖定統計 DBMS_STATS.LOCK_TABLE_STATS、使用 OPTIMIZER_DYNAMIC_SAMPLING

進階:SQL Plan Management (SPM) 鎖定優質計畫 (11g+)


-- 1. 捕捉基線
ALTER SESSION SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES = TRUE;
-- 執行目標 SQL...

-- 2. 查看/固定基線
SELECT sql_handle, plan_name, enabled, accepted, fixed FROM dba_sql_plan_baselines;
EXEC DBMS_SPM.ALTER_SQL_PLAN_BASELINE(sql_handle=>'SYS_SQL_...', plan_name=>'...', attribute_name=>'FIXED', attribute_value=>'YES');

-- 3. 演進驗證 (自動驗證新計畫優於基線才接受)
EXEC DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(sql_handle=>'SYS_SQL_...');

結語

**RBO 是歷史,CBO 是現在與未來**。掌握 OPTIMIZER_MODE 三層控制、**統計資訊自動化收集與品質監控**、以及 **SPM 執行計畫穩定機制**,是現代 Oracle DBA/開發的核心童子功。切記:**沒有統計資訊的 CBO 比 RBO 更危險**。

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