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

資料庫效能調優核心技術:嵌套循環連接執行計畫深度解析

     編輯:Oracle 資料庫基礎

系列定位與環境

本系列第三篇專講 Nested Loops Join (NLJ),前篇覆蓋單表掃描,後續將講 Hash Join、Merge Join、子查詢轉換。達夢、Oracle、SQL Server 在執行計畫邏輯上無本質差異。本文採 Oracle 10g 實測,解析基於執行計畫、10053 Trace 反推,大方向準確。

顯示執行計畫兩大工具

  • SET AUTOTRACE ON EXPLAIN:執行 SQL 並顯示計畫與統計,**會真正跑完 SQL**,慢查詢慎用。
  • EXPLAIN PLAN FOR ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);:不執行 SQL,僅生成計畫,適合慢查詢分析。

NLJ 執行計畫樹狀結構閱讀指南

每個操作有 ID 與 Parent ID。NESTED LOOPS 為父節點,第一個 Child 為 Outer Table (驅動表/外部表),第二個 Child 為 Inner Table (被驅動表/內部表)。控制權在父節點與子節點間流轉,類似雙層迴圈。
Predicate Information 區區分 Access (索引/雜湊鍵值定位) 與 Filter (取得行後再過濾)。

三種 NLJ 變體逐步演示

1. 無索引 NLJ:笛卡爾積 + 過濾

SELECT /*+ USE_NL(t2) */ c1,c2 FROM t1 INNER JOIN t2 ON c1=d2;

計畫:NESTED LOOPS → TABLE ACCESS FULL T1 (Outer) → TABLE ACCESS FULL T2 (Inner, Filter: C1=D2)

邏輯等同:

FOR rec1 IN (SELECT * FROM t1) LOOP
  FOR rec2 IN (SELECT * FROM t2) LOOP
    IF rec1.c1 = rec2.d2 THEN PIPE ROW(rec1.c1, rec1.c2); END IF;
  END LOOP;
END LOOP;

控制流:Outer 取一行 → 交給 NLJ → NLJ 驅動 Inner 全掃描 → 符合 Filter 者上傳 → 直到 Inner 耗盡 → Outer 取下一行。Inner 表重複全掃描 Outer 行數次。

2. 非唯一索引 NLJ:INDEX RANGE SCAN

SELECT /*+ INDEX(t2) */ c1,c2,d1 FROM t1 INNER JOIN t2 ON c1=d1;

計畫:NESTED LOOPS → TABLE ACCESS FULL T1 → INDEX RANGE SCAN IT2D1 (Access: C1=D1)

關鍵差異:Inner 端改用索引範圍掃描,Access("C1"="D1") 表示用 Outer 當前行的 C1 值去 B-Tree 定位。因非唯一索引,可能返回多行,**NLJ 需重複呼叫 Index Range Scan 直到鍵值不匹配**,控制權在 NLJ 與 Index Scan 間多次切換。

3. 唯一索引 NLJ:INDEX UNIQUE SCAN

DROP INDEX it2d1; CREATE UNIQUE INDEX iut2d1 ON t2(d1);
SELECT /*+ INDEX(t2) */ c1,c2,d1 FROM t1 INNER JOIN t2 ON c1=d1;

計畫:NESTED LOOPS → TABLE ACCESS FULL T1 → INDEX UNIQUE SCAN IUT2D1 (Access: C1=D1, Cost=0)

唯一索引保證至多 1 行匹配,**Index Unique Scan 只需呼叫一次即返回或結束**,NLJ 不再重複驅動 Inner,直接把控制權還給 Outer 取下一行。Cost 從 4 降至 2,效能顯著提升。

NLJ 核心特徵總結

維度無索引非唯一索引唯一索引
Inner 存取Full Scan + FilterIndex Range Scan (多次)Index Unique Scan (單次)
適用場景小表驅動小表、無索引Outer 少、Inner 有非唯一索引Outer 少、Inner 有唯一索引/PK
Cost 特徵最高中等最低 (Cost=0 索引存取)

實戰判讀提示

  • 若 Outer 表行數龐大 (如百萬) 且 Inner 無高選擇性索引,NLJ 會極慢 → 應改 Hash Join。
  • 關注 Predicate Information 中的 Access vs Filter,Access 才是真正的索引定位鍵。
  • 10g+ DBMS_XPLAN.DISPLAY_CURSOR 可顯示實際執行時的 Starts (啟動次數),NLJ 的 Inner Starts 應 ≈ Outer 返回行數,驗證驅動關係。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved