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

Oracle 優化器選擇指南:RBO、CBO、統計資訊收集、Bind Variable 與 SQL Plan Management

     編輯:Oracle 資料庫基礎

三種優化器模式

模式參數值特點適用性
RULE (RBO)OPTIMIZER_MODE=RULE固定規則、不看統計、已棄用不建議使用
COST (CBO)OPTIMIZER_MODE=ALL_ROWS / FIRST_ROWS_n成本模型、依統計資訊、預設所有生產環境
CHOOSEOPTIMIZER_MODE=CHOOSE有統計用 CBO、無統計用 RBO不建議 (行為不可預期)

CBO 核心依賴:統計資訊

必收集統計項目

  • 表:行數、區塊數、平均行長
  • 欄位:NDV (非重複值數)、NULL 數、密度、直方圖
  • 索引:層級、葉區塊、叢集因子、非重複鍵值
  • 系統:CPU 速度、I/O 吞吐 (DBMS_STATS.GATHER_SYSTEM_STATS)

收集指令

-- 基本收集
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMP', CASCADE => TRUE);

-- 生產環境建議參數
EXEC DBMS_STATS.GATHER_TABLE_STATS(
  ownname => 'SCOTT', tabname => 'EMP',
  estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
  method_opt => 'FOR ALL COLUMNS SIZE AUTO',
  cascade => TRUE, degree => 4, granularity => 'AUTO');

-- 系統統計 (關鍵!)
EXEC DBMS_STATS.GATHER_SYSTEM_STATS('INTERVAL', 60);  -- 工作負載模式
-- 或
EXEC DBMS_STATS.GATHER_SYSTEM_STATS('NOWORKLOAD');    -- 模擬模式

Bind Variable 與游標共享

硬解析 vs 軟解析

  • Hard Parse:Library Cache Miss → 語法/語義檢查 → 優化 → 存入 Cache
  • Soft Parse:Library Cache Hit → 直接執行

CURSOR_SHARING 參數

最佳實踐:應用層使用 Bind Variable,資料庫保持 EXACT。

SQL Plan Management (SPM) - 11g+ 計畫穩定

運作流程

  1. Capture:自動/手動載入計畫至 SQL Plan Baseline
  2. Select:優化器僅選擇 Accepted 的計畫
  3. Evolve:新計畫驗證通過後標記 Accepted

關鍵操作

-- 啟用自動捕獲
ALTER SYSTEM SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES = TRUE;

-- 手動載入 (從 Cursor Cache)
DECLARE
  n PLS_INTEGER;
BEGIN
  n := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
    sql_id => 'abc123', fixed => 'YES');
END;
/

-- 查詢 Baseline
SELECT sql_handle, plan_name, enabled, accepted, fixed, origin
FROM dba_sql_plan_baselines;

-- 演進驗證
SET SERVEROUTPUT ON
DECLARE
  rpt CLOB;
BEGIN
  rpt := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(
    sql_handle => 'SYS_SQL_123', verify => 'YES', commit => 'YES');
  DBMS_OUTPUT.PUT_LINE(rpt);
END;
/

-- 固定計畫 (不再演進)
EXEC DBMS_SPM.ALTER_SQL_PLAN_BASELINE(plan_name => 'PLAN_1', attribute_name => 'FIXED', attribute_value => 'YES');

存取路徑選擇原則

值行為風險
EXACT (預設)完全匹配 (含字面值)字面值 SQL 導致 Hard Parse 暴增
FORCE強制替換字面值為 Bind Variable可能產生次優計畫、直方圖失效
SIMILAR (11g 棄用)類似 FORCE 但保留直方圖同上
路徑觸發條件Hint 強制
Full Table Scan無索引、低選擇性 (>5-10%)、小表、平行查詢FULL(t)
Index Range Scan高選擇性、前導欄位有範圍條件INDEX(t idx_name)
Index Unique Scan唯一索引、等值條件含所有鍵欄位INDEX(t idx_name)
Index Fast Full Scan需所有索引欄位、無排序需求INDEX_FFS(t idx_name)
Index Skip Scan複合索引前導欄位低基數、後續欄位高選擇性INDEX_SS(t idx_name)
Full Index Scan索引含所有查詢欄位、需排序INDEX(t idx_name)

常見計畫錯誤排查步驟

  1. 確認統計資訊新鮮度:SELECT last_analyzed FROM dba_tables WHERE table_name='...'
  2. 檢查直方圖:SELECT column_name, histogram FROM dba_tab_col_statistics WHERE table_name='...'
  3. 查看實際執行計畫:SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id, child_number, 'ALL'))
  4. 比較估算 vs 實際行數 (E-Rows vs A-Rows)
  5. 若估算嚴重偏差 → 收集直方圖、延伸統計、動態採樣
  6. 若仍錯誤 → SQL Profile / SPM Baseline / Hint (最後手段)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved