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

Oracle EXPLAIN PLAN 與 AUTOTRACE 實戰:從執行計畫輸出到 NESTED LOOPS 解讀技巧

     編輯:Oracle 資料庫基礎

兩大分析工具:EXPLAIN PLAN vs AUTOTRACE

特性EXPLAIN PLANSET AUTOTRACE
是否執行 SQL否(僅解析)是(實際執行)
適用場景DML 不想執行、生產環境只讀分析完整效能分析、含實際統計
輸出內容預估計畫、Cost、Cardinality實際計畫 + 邏輯讀/物理讀/排序/網路統計
權限需求PLUSTRACE rolePLUSTRACE role

EXPLAIN PLAN 標準流程

-- 1. 確保 PLAN_TABLE 存在(通常預設有公用同義詞)
-- 2. 產生計畫
EXPLAIN PLAN FOR
SELECT e.ename, d.dname 
FROM emp e, dept d 
WHERE e.deptno = d.deptno;

-- 3. 顯示計畫(需執行一次)
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

AUTOTRACE 實戰:更直觀的完整輸出

SET AUTOTRACE TRACEONLY EXPLAIN  -- 僅顯示計畫,不執行(同 EXPLAIN PLAN)
SET AUTOTRACE TRACEONLY STATISTICS -- 僅顯示統計,不顯示資料
SET AUTOTRACE TRACEONLY            -- 計畫 + 統計,不顯示資料(推薦)
SET AUTOTRACE ON                   -- 計畫 + 統計 + 結果集

-- 實際範例
SET AUTOTRACE TRACEONLY
SELECT * FROM dept, emp WHERE emp.deptno = dept.deptno;

輸出解讀範例

Execution Plan
----------------------------------------------------------
Plan hash value: 1234567890

---------------------------------------------------------------------------
| Id | Operation          | Name    | Rows | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0| SELECT STATEMENT   |         |   14 |   728 |     5  (20)| 00:00:01 |
|   1|  NESTED LOOPS      |         |   14 |   728 |     5  (20)| 00:00:01 |
|   2|   TABLE ACCESS FULL| EMP     |   14 |   448 |     3  (34)| 00:00:01 |
|   3|   TABLE ACCESS BY  | DEPT    |    1 |    20 |     1   (0)| 00:00:01 |
|   4|    INDEX UNIQUE SCAN| PK_DEPT |    1 |       |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          0  recursive calls
          2  db block gets
         30  consistent gets
          0  physical reads
          0  redo size
       2598  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         14  rows processed

執行順序解讀鐵律:由內而外、由上而下

  1. 最內層(縮排最深)先執行:Id 4 INDEX UNIQUE SCAN → Id 3 TABLE ACCESS BY INDEX ROWID
  2. 同層級按 Id 小到大:Id 2 TABLE ACCESS FULL EMP → Id 4/3 鏈
  3. 父節點等待所有子節點產生資料後執行:Id 1 NESTED LOOPS 串流連接 Id 2 與 Id 3/4 的結果

實際執行步驟還原

  1. Step 1:TABLE ACCESS FULL EMP(Id 2)全表掃描 EMP,產生 14 列驅動資料
  2. Step 2:INDEX UNIQUE SCAN PK_DEPT(Id 4)對每筆 EMP 的 DEPTNO 走 PK 索引查 DEPT
  3. Step 3:TABLE ACCESS BY INDEX ROWID DEPT(Id 3)由 Rowid 取 DEPT 列資料
  4. Step 4:NESTED LOOPS(Id 1)將兩邊結果逐列連接,輸出最終結果

NESTED LOOPS 特例:驅動表(外層)通常是 Id 較小的子節點(此處 Id 2)。Oracle 11g+ 會在計畫顯示 NESTED LOOPS 下分 NESTED LOOPS OUTER 等細節,但核心邏輯不變。

關鍵 Operation 類型速查

Operation含義效能暗示
TABLE ACCESS FULL全表掃描大表需檢視是否缺索引/統計過期
TABLE ACCESS BY INDEX ROWID索引回表正常;若次數極大考慮覆蓋索引
INDEX UNIQUE SCAN唯一索引單值查找極佳(PK/UK 查找)
INDEX RANGE SCAN索引範圍掃描良好(範圍查詢、複合索引前綴)
INDEX FULL SCAN索引全掃描次於 RANGE SCAN,排序/全索引掃描
INDEX FAST FULL SCAN索引快速全掃(多區塊讀)類似 FTS 但僅讀索引,適合 COUNT(*)
HASH JOIN雜湊連接大表連接優選,需足夠 PGA
SORT GROUP BY排序分組大量排序關注 TEMP 空間

進階:DBMS_XPLAN 顯示參數全解

-- 基本顯示
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

-- 含別名、成本、基數、位元組
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', NULL, 'TYPICAL'));

-- 含 Outline Hint(可直接複製成 Hint 固定計畫)
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', NULL, 'ADVANCED'));

-- 含實際執行統計(需先執行 SQL,配合 GATHER_PLAN_STATISTICS Hint)
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM emp WHERE deptno = 20;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST'));

第三方工具:TOAD、SQL Developer、OEM

圖形化介面提供:

  • 計畫樹狀圖、Cost 佔比圖
  • 滑鼠懸停顯示 Cardinality、Bytes、Predicate
  • 計畫比較(兩次執行差異)
  • SQL 優化建議(自動建議索引/直方圖/改寫)

命令列 AUTOTRACE + DBMS_XPLAN.DISPLAY_CURSOR 是 DBA 隨身利器,無需安裝客戶端即可在伺服器端完成 90% 分析工作。

總結

掌握 SET AUTOTRACE TRACEONLY 獲取實際計畫與統計,配合 DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST') 深度剖析,**核心能力在於「由內而外、由上而下」還原真實執行順序**,識別 FULL SCAN、CARDINALITY 嚴重偏差、NESTED LOOPS 驅動表選擇不當等效能殺手。建議將「執行計畫閱讀」列入 DBA/開發核心技能矩陣定期演練。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved