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

Oracle 查詢優化實戰:執行計劃深度解讀與驅動表選擇策略

     編輯:Oracle 資料庫基礎

執行計劃核心欄位解讀

優化器模式判斷

SELECT STATEMENT Optimizer=CHOOSE (Cost=1234 Card=1 Bytes=14)
  TABLE ACCESS FULL LARGE_TABLE [:Q65001] [ANALYZED]
  • Optimizer=CHOOSE:初始化參數值,非實際使用優化器
  • Cost=數值:CBO 模式(有成本計算)
  • Cost=空值或無 Cost:RBO 模式
  • [:Qxxxxx]:平行查詢 Slave 進程
  • [ANALYZED]:物件有統計資訊,CBO 可用

優化器模式對照表

Optimizer 值實際優化器
ALL_ROWS / FIRST_ROWS / FIRST_ROWS_nCBO
RULERBO
CHOOSE + Cost=數值CBO
CHOOSE + Cost=空RBO

多表連接執行計劃深度分析

測試場景

  • 表 A、B、C 均為大表
  • A 有複合索引 INX_COL12A (col1, col2),col1 為引導欄
  • 查詢:WHERE B.col3=10 AND A.col1=B.col1 AND A.col2=C.col2 AND C.col3=5

執行計劃結構

SELECT STATEMENT Optimizer=CHOOSE
  0 MERGE JOIN
    1 SORT (JOIN)
      2 NESTED LOOPS
        3 TABLE ACCESS (FULL) OF 'B'
        3 TABLE ACCESS (BY INDEX ROWID) OF 'A'
          5 INDEX (RANGE SCAN) OF 'INX_COL12A' (NON-UNIQUE)
    1 SORT (JOIN)
      7 TABLE ACCESS (FULL) OF 'C'

連接順序推導邏輯

  1. 移除索引掃描行(輔助操作,非主要存取)
  2. 最右、最上優先:縮進最多、位置最上者最先執行
  3. 結果:TABLE ACCESS FULL B → 驅動表(外部表)
  4. 連接順序:B → A → C

為何 B 為最佳驅動表?

  • B 有過濾條件 col3=10,全表掃描後產生小結果集
  • 連接條件 A.col1=B.col1 可用 A 索引引導欄
  • 若 C 為驅動表:A.col2=C.col2 無法用索引(col2 非引導欄),NL 效能差

優化器干預:HINT 強制連接順序

SELECT /*+ ORDERED */ A.col4
FROM B, A, C
WHERE B.col3 = 10
  AND A.col1 = B.col1
  AND A.col2 = C.col2
  AND C.col3 = 5;

ORDERED 指示 CBO 依 FROM 子句順序連接,配合將驅動表寫在最前。

RBO 模式驗證實驗

實驗結論

  • 文檔稱「FROM 右到左選擇驅動表」未驗證成功
  • 實測:RBO 仍考慮索引存在性與 WHERE 條件,非單純順序決定
  • 刪除索引後:RBO 轉為 MERGE JOIN 全表掃描
  • RBO 無法用 HINT 強制 NL(會隱性切換 CBO)

驅動表選擇黃金法則

原則說明
有過濾條件的表優先WHERE 子句可大幅縮減結果集
連接欄位有索引引導欄支援高效 NESTED LOOPS
小結果集驅動大表減少內部表存取次數
統計資訊必須準確CBO 依賴統計資訊決策

執行計劃閱讀檢查清單

  1. 識別優化器模式(CBO/RBO)
  2. 移除索引掃描輔助行
  3. 按「最右最上」找首個表存取 → 驅動表
  4. 追蹤連接順序與連接方式(NL/MSJ/HJ)
  5. 檢查索引使用情況(RANGE SCAN vs FULL SCAN)
  6. 評估驅動表選擇是否最優,否則加 HINT 或重寫 SQL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved