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

DB2 表連接原理深度解析:NLJ、Merge Join、Hash Join 三大演算法機制與優化器選擇策略

     編輯:DB2 教學

DB2 優化器在執行連接查詢時,可選擇 巢狀迴圈連接、合併連接、雜湊連接 三種演算法。本文深入剖析三者運作機制、外部/內部表選擇邏輯、適用條件限制、記憶體/磁碟溢寫行為,並解析優化器基於成本模型的選擇策略,助您理解執行計畫、進行針對性調優。

一、通用概念:外部表與內部表

  • 連接雙方必有一外部表、一內部表。
  • 外部表僅掃描一次;內部表視演算法可能掃描多次。
  • 優化器依成本模型(表大小、索引、緩衝區、謂詞、排序需求)決定誰為外部/內部表。
  • 多表連接時,優化器每次僅連接兩表,產生中間結果集再繼續連接。

二、巢狀迴圈連接

運作流程

  1. 掃描外部表每一列。
  2. 對每一外部列,在內部表尋找匹配列:
  • 全表掃描內部表:逐列比對(成本極高)。
  • 索引查找:若連接欄位在內部表有索引,直接定位匹配列(大幅降低存取量)。

優化器選擇外/內表考量因子

  • 表大小(小表優先做外部)
  • 緩衝區命中率
  • 連接謂詞選擇率
  • 排序需求
  • 內部表連接欄位是否有索引
  • 連接欄位不可為 LONG/LOB

適用場景

  • 外部表極小、內部表有高選擇率索引。
  • 需保持外部表輸出順序。

三、合併連接

前置條件

  • 至少一個等值連接謂詞(table1.col = table2.col)。
  • 雙方輸入依連接鍵已排序(利用索引順序掃描或顯式排序)。
  • 連接欄位不可為 LONG/LOB。

運作流程

  • 同步掃描兩表(類似合併排序的 merge 階段)。
  • 外部表與內部表各掃描一次(除非外部表有重複值,需回溯內部表部分區段)。
  • 優化器傾向選「重複值較少」的表為外部表,但最終仍以成本模型決定。

優勢

  • 無需重複存取內部表,大表連接效能優於 NLJ。
  • 輸出順序符合連接鍵排序,利於後續 ORDER BY 消除排序。

四、雜湊連接

前置條件

  • 一或多個等值連接謂詞,對應欄位型態完全相同(CHAR 長度、DECIMAL 精度/小數位皆同)。
  • 連接欄位不可為 LONG/LOB。
  • 需設定環境變數啟用(DB2_HASH_JOIN=ON 或資料庫配置)。

運作流程(兩階段)

  1. 建構階段:掃描內部表(建構表),依連接鍵計算雜湊碼,將列分散至記憶體雜湊分區。記憶體不足時,分區溢寫至磁碟臨時表。
  2. 探測階段:掃描外部表(探測表),對每列計算相同雜湊碼,定位對應分區比對實際連接鍵值。匹配分區在記憶體即時比對;在磁碟則將探測列亦寫入臨時表,最後處理臨時表完成匹配。

關鍵特性

  • 支援多個等值謂詞(Merge Join 僅支援單一等值謂詞)—— 重大優勢。
  • 優化器傾向選較小表為建構表,避免溢寫磁碟。
  • 不保證輸出順序(溢寫磁碟會打亂順序),若需有序輸出需額外排序。

五、三大演算法選擇決策邏輯

場景 優先考慮 關鍵原因
小表驅動大表、大表有高選擇率索引NLJ索引查找成本極低
大表連接、雙方可利用索引順序/預排序Merge Join單掃描、無雜湊建構開銷、保持順序
大表連接、多等值條件、無索引順序、記憶體充足Hash Join多條件支援、CPU 密集但 I/O 少、平行化友善
需保持輸出順序、且大表無索引順序Merge Join / NLJHash Join 可能溢寫破壞順序

六、調優實務建議

  1. 收集統計資料(RUNSTATS),讓優化器擁有準確基數估計。
  2. 在連接欄位建立適當索引,啟用 NLJ/Merge Join 路徑。
  3. 大型數倉查詢:啟用 Hash Join(DB2_HASH_JOIN=ON)、配置足夠 SORTHEAP/SHEAPTHRES 避免溢寫。
  4. 檢視執行計畫(db2exfmt),確認實際選擇的演算法、外/內表角色、溢寫警告。
  5. 必要時用 OPTIMIZATION LEVEL 或 JOIN METHOD 提示強制指定(謹慎使用)。

小結

理解 NLJ、Merge Join、Hash Join 的底層機制與優化器決策邏輯,是 SQL 調優從「試錯」進階到「精準優化」的關鍵。善用統計資料、索引設計與記憶體配置,引導優化器選擇最適演算法,即可獲得穩定高效的連接效能。

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