痛點:複雜多表連接的剖析風暴
7 表以上連接,可能連接順序超過 40,000 種,優化器剖析時間可達 30 分鐘,嚴重拖累系統吞吐。
技巧一:ORDERED Hint —— 固定連接順序,跳過排列組合
語法與原理
SELECT /*+ ORDERED USE_NL(b) PARALLEL(e,4) */
e.ename, e.hiredate, b.comm
FROM emp e, bonus b
WHERE e.ename = b.ename;
ORDERED:強制按 FROM 子句順序連接,首表為驅動表
- 驅動表選擇原則:回傳行數最少 的表 (經過 WHERE 過濾後)
- 搭配
USE_NL、PARALLEL 等 Hint 組合出最佳執行計劃
適用場景
- 開發者對資料分布、業務邏輯有深度理解
- 統計資訊過時/缺失,優化器誤判連接順序
- 緊急上線修復,無時間重收統計資訊
技巧二:ORDERED_PREDICATES Hint —— 掌控 WHERE 條件評估順序
預設評估規則 (無 Hint 時)
- 子查詢優先於外層 WHERE 條件
- 無函數/子查詢的布爾條件:逆序評估 (最後寫的最先評估)
- 含內建函數的條件:按預估評估成本 遞增 排序
強制順序評估
SELECT /*+ ORDERED_PREDICATES */ *
FROM large_table
WHERE expensive_plsql_func(col1) = 'Y' -- 昂貴函數
AND col2 = 100 -- 廉價索引欄位
AND col3 > SYSDATE - 30; -- 範圍條件
加上 Hint 後,按寫入順序評估。關鍵用法:將最具過濾力、成本最低的條件寫在最前面,實現「早剪枝」。
限制
無法控制索引鍵存取路徑的評估順序 (由存取路徑決定)。
技巧三:optimizer_search_limit 參數 —— 截斷連接順序搜尋空間
機制
控制基於成本優化器 (CBO) 評估的最大連接順序組合數。預設值 5。
- 表數 ≤
optimizer_search_limit:窮盡搜尋所有順序
- 表數 > 該值:採用啟發式演算法 (貪婪/遺傳),不保證全域最優
- 同時控制
STAR Hint 的啟用門檻
調整策略
| 場景 | 建議值 | 理由 |
| 常規 OLTP (表數 < 10) | 5 (預設) | 平衡剖析時間與計劃品質 |
| 複雜報表/ETL (表數 10~20) | 8~12 | 允許更充分搜尋,剖析時間可接受 |
| 極大連接 (>20 表) 或剖析超時 | 3~5 | 強制啟發式,犧牲最優性換穩定剖析時間 |
修改方式
-- Session 級 (測試用)
ALTER SESSION SET optimizer_search_limit = 8;
-- 系統級 (需重啟或 SPFILE)
ALTER SYSTEM SET optimizer_search_limit = 8 SCOPE=SPFILE;
綜合實戰清單
- 優先收集完整統計資訊 (
DBMS_STATS.GATHER_TABLE_STATS),讓 CBO 自主決策
- 統計資訊可靠時,避免濫用 Hint,維護成本高
- 必須用 Hint 時:
ORDERED 固定連接順序 + ORDERED_PREDICATES 固定過濾順序 + optimizer_search_limit 限制搜尋空間
- 建立 SQL Plan Baseline (11g+) 固化優質計劃,替代硬編碼 Hint
- 上一篇文章: 技術選型決策指南:Oracle + WebDB vs SQL Server + Visual Studio 深度利弊對比
- 下一篇文章: Oracle 歸檔模式完全指南:啟用、查詢、參數配置與 10g/11g/12c/19c 版本差異
Copyright ©
程式碼之家 All Rights Reserved