| 連接方法 | 能否有效利用內表索引 |
| Nested Loops | 是** |
| Sort Merge Join | 僅能避免排序,無法加速存取 |
| Hash Join | 幾乎無影響(需建雜湊表) |
若 Optimizer 選擇 Hash Join,內表索引再好也用不上。
4. 連接順序是否允許索引生效
- 外表(Driving Table)永遠**全表掃描**
- 若大表在外、小表在內且有索引 → 索引浪費
- 對策:
/*+ ORDERED */ 或 /*+ LEADING(t_small) */ 強制小表驅動
5. 是否涉及資料字典表/視圖
- 字典表無統計資訊 → CBO 產生極差計劃
- **嚴禁自行分析字典表**,恐導致死鎖/效能崩壞
- 對策:改寫查詢避免直接查字典,或用 Hint 強制 RBO
6. 隱性資料型態轉換
WHERE char_col = 123 → Oracle 隱性 TO_NUMBER(char_col) → 索引失效
WHERE num_col = '123' → 隱性 TO_CHAR(num_col) → 索引失效
- 對策:應用層嚴格型別綁定,SQL 明確轉換
TO_CHAR/TO_NUMBER/TO_DATE
進階診斷工具
-- 1. 觀察實際執行計劃
EXPLAIN PLAN FOR SELECT ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 2. 10053 追蹤(CBO 決策內幕)
ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';
-- 執行 SQL 後查看 trace 檔
-- 3. 統計資訊健康度
SELECT table_name, last_analyzed, num_rows, blocks
FROM user_tables
WHERE last_analyzed < SYSDATE - 30; -- 超過 30 天未分析
最佳實務總結
- **統計資訊是 CBO 生命線**:定期
DBMS_STATS.GATHER_TABLE_STATS,採樣 10-20%
- **索引設計遵循「選擇性高、前導欄在 WHERE」原則**
- **避免隱性轉換**:應用程式使用繫結變數正確型別
- **複雜查詢用 Hint 微調而非硬編碼**
- **定期收集系統統計**:
DBMS_STATS.GATHER_SYSTEM_STATS 讓 CBO 瞭解硬體特性
索引不被使用通常不是 Bug,而是優化器基於成本模型的理性選擇。掌握上述六大排查步驟,您就能像優化器一樣思考,精準診斷、有效干預。
- 上一篇文章: VMware 虛擬機 Red Hat Linux 安裝 Oracle 9i 完整實戰筆記:從磁碟規劃到環境變數配置
- 下一篇文章: DBMS_METADATA.GET_DDL:一行指令輕鬆提取表、索引、程序完整 DDL 定義
Copyright ©
程式碼之家 All Rights Reserved