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

Oracle 執行計畫優化:ORDERED Hint 控制連接順序與優化器搜尋上限參數

     編輯:Oracle 資料庫基礎

前言

多表連接時,優化器需評估所有連接順序排列組合 (N!),表數超過 10 即達百萬億級,導致硬解析極慢。本文詳細說明 OPTIMIZER_SEARCH_LIMIT、OPTIMIZER_MAX_PERMUTATIONS 參數與 ORDERED、LEADING Hint 如何協作控制優化器搜尋空間,並給出實戰建議。

優化器連接順序搜尋機制

  • N 表連接有 N! (階乘) 種可能順序 (6 表 = 720 種、15 表 ≈ 1.3 兆種)。
  • 優化器透過動態規劃 (Dynamic Programming) 避免窮舉,但仍受參數限制搜尋深度。

關鍵參數

關係:優化器先檢查 SEARCH_LIMIT,再受 MAX_PERMUTATIONS 總上限約束。

手工指定連接順序:ORDERED & LEADING Hint

ORDERED

強制依 **FROM 子句順序** 連接,第一張表為驅動表 (Outer Table)。


SELECT /*+ ORDERED USE_NL(b) */ e.ename, b.comm
FROM   emp e, bonus b
WHERE  e.ename = b.ename;
  • 常搭配 USE_NL, USE_HASH, USE_MERGE 指定連接方式。
  • 適用於 **數據倉庫大查詢 (4+ 表)**,消除優化器搜尋開銷。

LEADING (更靈活,10g+ 推薦)

指定**連接順序清單**,不綁定 FROM 子句順序。


SELECT /*+ LEADING(e d s b) USE_HASH(e d) USE_NL(s b) */
       ...
FROM   emp e, dept d, sal s, bonus b
WHERE  ...;
  • LEADING(e d s b) 表示先連 e-d,再連 s,最後連 b。
  • 可部分指定:LEADING(e d) 只固定前兩表,其餘交給優化器。

實戰調優流程

  1. **收集完整統計資訊** (含直方圖) → 確保優化器基數估算準確。
  2. **暫時調大 SEARCH_LIMIT** (Session 級) 讓優化器窮舉找出最佳順序:
    ALTER SESSION SET OPTIMIZER_SEARCH_LIMIT = 10; -- 表數
  3. 執行查詢,用 DBMS_XPLAN.DISPLAY_CURSOR 觀察最佳順序。
  4. 將最佳順序固化為 LEADING Hint 寫入 SQL,或建立 **SQL Plan Baseline / Stored Outline** 持久化。
  5. 恢復參數預設值,避免影響其他查詢解析時間。

進階:SQL Plan Management (SPM) 持久化執行計畫


-- 1. 捕捉當前最佳計畫為 Baseline
DECLARE
  l_plans PLS_INTEGER;
BEGIN
  l_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
    sql_id => 'abc123xyz',
    plan_hash_value => 1234567890,
    fixed => 'YES'  -- 固定不演化
  );
END;
/

總結

「統計資訊是基石,Hint 是手術刀,Baseline 是保險箱。優先修正統計,再用 LEADING 微調,最後用 SPM 固化。」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數預設值作用
OPTIMIZER_SEARCH_LIMIT5表數 ≤ 此值時,**窮舉所有排列**;表數 > 此值時,改用啟發式搜尋 (貪婪/動態規劃),不保證最優。
OPTIMIZER_MAX_PERMUTATIONS80,000**最大評估排列數上限** (11g 後已隱性/棄用,由動態規劃內部控制)。若達上限則停止搜尋,選擇目前最低 Cost 順序。