2017年10月19日 星期四

[SQL] JOIN - Merge Join

  • Merge Join (合併聯結)
    • 基本原則: Join 的兩個輸入資料表比對的 "資料行",必須事先經過排序,若沒經過排序,執行過程中將會進行 "排序" 作業,才能進行 "Merge Join"
      • 因此沒排序的兩資料表進行比對 "資料行",使用 "Merge Join" 作業,查詢效率並不會比較好
      • 如 "Merge Join" 輸入的兩資料表所比對 "資料行",已經有 "B-tree" 索引取得已排序資料進行比對,這樣 "Merge Join" 查詢效率為最快速 "Merge" 演算法
  • 資料庫使用 Adventure Works for SQL Server 2012 的資料表 Sales.SalesOrderHeader 與 Sales.SalesOrderDetail 創建 2 個 table 如下
    • tbSalesOrderHeader
      • unique Clustered index:SalesOrderID
    • tbSalesOrderDetail
      • unique Clustered index:SalesOrderID, SalesOrderDetailID
    • 查詢
select *
from tbSalesOrderHeader o
join tbSalesOrderDetail od ON o.SalesOrderID = od.SalesOrderID
where o.SalesOrderID between 70000 and 80000

select *
from tbSalesOrderHeader o
join tbSalesOrderDetail od ON o.SalesOrderID = od.SalesOrderID
where o.SalesOrderID = 70000
    • 查詢結果
      • 查詢 1:查詢範圍 SalesOrderID 70000 ~ 80000 (大量資料),採用 "Merge Join"
      • 查詢 2:查詢範圍 SalesOrderID 70000  (小量資料),採用 "Loop Join"
      • 此兩資料表連結是透過 "SalesOrderID",因  tbSalesOrderHeader 的 SalesOrderID 為 "叢集索引" 的 "鍵值資料行",而 tbSalesOrderDetail 的 SalesOrderID 為 "叢集索引" 的 "複合鍵值資料行" 的第一個位置,因此 SalesOrderID 在此兩資料行皆已排序,所以查詢1 Query Optimizer 採用 "Merge Join"
    • Result:
      1. 小型資料查詢採用 "Loop Join",而 "Merge Join" 適合查詢大量資料
      2. "Merge Join" 最適合兩資料行皆事先排序,最佳情況是雙方資料行皆已建立 "索引"
      3. 注意:兩資料表間應存有 "Primary Key (PK)" 與 "Foreign Key (FK)" 的對應關係
        • Foreign Key (FK):會是排序過且唯一的 "叢集索引"
        • Foreign Key (FK):不一定會經過排序的 "索引"
  • REF:
    • SQL Server 效能調校

沒有留言:

張貼留言