| 特性 | RBO (Rule-Based) | CBO (Cost-Based) | |
|---|---|---|---|
| 決策依據 | 固定規則排名 (索引 > 全表) | 統計資訊計算 Cost,取最低 | |
| 對資料敏感度 | 不敏感 | 高度敏感 | |
| 新特性支援 | 無 (已停止開發) | 完整支援 (並行、星型、雜湊連接等) | |
| 預設模式 (7.0+) | CHOOSE:有統計用 CBO,無統計用 RBO |
| # | 原因 | 檢查方法 | 對策 |
|---|---|---|---|
| 1 | 優化器模式非 CBO | SHOW PARAMETER optimizer_mode | 設 ALL_ROWS,收集統計資訊 |
| 2 | 索引欄位未出現在 WHERE | 檢查 SQL 文本 | 重寫 SQL 或建立覆蓋索引 |
| 3 | 連接方式非 Nested Loop | 執行計劃看 HJ/SMJ | 用 USE_NL Hint 或調整驅動表 |
| 4 | 連接順序導致外表全掃 | 執行計劃連接順序 | ORDERED Hint 指定小表為驅動 |
| 5 | 涉及字典表/視圖無統計 | 計劃出現 SYS 物件 | 避免查字典;禁自行分析字典 |
| 6 | 索引欄位被函數包裹 | WHERE TO_CHAR(dt)='2024' | 建函數索引或改寫 dt >= ... AND dt < ... |
| 7 | 隱性型別轉換 | WHERE char_col = 123 → 隱性 TO_NUMBER | 顯式轉換 WHERE char_col = '123' |
| 8 | 統計資訊過時/缺失 | LAST_ANALYZED 過久 | 定期 GATHER_TABLE_STATS + 直方圖 |
| 9 | 索引選擇性過低 (如性別、狀態) | DISTINCT_KEYS / NUM_ROWS < 1% | 建位圖索引 / 組合索引 / 分區裁剪 |
| 10 | 索引欄位含 NULL 需回傳 | COUNT(*)、WHERE col IS NULL | 索引不存全 NULL;用 COUNT(1) 或函數索引 |
| 11 | 並行查詢 (PQO) 強制全掃 | 計劃有 PX SEND/RECEIVE | 調整 PARALLEL_DEGREE_POLICY 或 Hint |
| 12 | Bind 變量窺探導致計劃固化 | WHERE col > :b1 首次執行值影響 | OPTIMIZER_ADAPTIVE_CURSOR_SHARING / BIND_AWARE Hint |
-- 建立 PLAN_TABLE (一次)
@$ORACLE_HOME/rdbms/admin/utlxplan.sql
SET AUTOTRACE ON
SELECT ...; -- 顯示計劃、Cost、邏輯讀、物理讀、Bytes 等
-- 1. 找目標 Session 的 SID, SERIAL#
SELECT sid, serial# FROM v$session WHERE username='APP_USER';
-- 2. 開啟追蹤 (需 DBA 權限)
EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(sid, serial#, TRUE);
-- 3. 執行業務流程...
-- 4. 關閉追蹤
EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(sid, serial#, FALSE);
-- 5. 格式化輸出
tkprof /path/to/ora_12345.trc output.txt EXPLAIN=user/pass SYS=NO
輸出檔包含每條 SQL 的執行計劃、CPU、Elapsed、邏輯/物理讀、Rows、庫存等完整指標,快速定位 Top SQL。
SELECT /*+ INDEX(t idx_col1) */ * FROM t WHERE col1 = :val;
規則:/*+ 緊跟 SELECT,+ 無空格,Hint 內部可空格分隔。