cmu15545筆記-Join演算法(Join Algorithms)

咪啪魔女發表於2024-11-15

目錄
  • Overview
  • Nested Loop Join
    • Naïve
    • Block
    • Index
  • Sort-Merge Join
  • Hash Join
    • Simple Hash Join
    • Partition Hash Join
  • 總結

Overview

輸出形式:早物化與晚物化(OLAP一般都是晚物化)

代價分析:一般用IO次數計算(最終結果可能落盤,也可能不落盤,所以我們只計算輸出結果之前的IO次數)。

Join左邊稱為外表(Outer Table),右邊稱為內表(Inner Join),外表一般是小表。

cmu15545筆記-Join演算法(Join Algorithms)

Nested Loop Join

Naïve

前提:緩衝區大小為3,一個外表輸入,一個內表輸入,一個輸出。

基本思想:雙重迴圈,對每一個元組(Tuple)進行配對,讀取S表m次。

Cost:\(M+(m*N)\)

image image

Block

前提:緩衝區大小為3,一個外表輸入,一個內表輸入,一個輸出。

基本思想:雙重迴圈,對每一個塊(Block,同頁Page)內進行配對,所以讀取S表M次。

Cost:\(M+(M*N)\)

image-20241115131544624

如果緩衝區容量為B,即可以容納B個塊(頁),B-2個塊用於外表輸入,一個塊用於內表輸入,一個塊用於輸出。

Cost:\(M+(⌈M/(B-2)⌉*N)\)

Index

前提:緩衝區大小為3,一個外表輸入,一個內表輸入,一個輸出。

基本思想:如果外部表有索引,那麼內層迴圈無需遍歷,查詢索引即可。

Cost:\(M+(m*C)\)

image-20241115132426075

Sort-Merge Join

基本思想:排序後的序列更容易找到匹配項。

分為兩個步驟:

  1. 排序:用任意排序方式,將R和S排序。
  2. 合併:移動兩個指標尋找匹配項,過程中可能需要回退指標。

這兩個步驟和上一節提到的外部歸併排序思想相同,但不是同一個東西。

SortCost(R):\(2M*(1 + ⌈ log_{B-1} ⌈M / B⌉ ⌉)\)

SortCost(S):\(2N*(1 + ⌈ log_{B-1} ⌈N / B⌉ ⌉)\)

MergeCost:\(M+N\)

Total Cost:Sort + Merge

當R中存的是相同元素,且S中也是時,指標需要一直回退,Sort-Merge Join退化為Nest Loop Join。

image-20241115140700767

image-20241115141209698

Hash Join

Simple Hash Join

基本思想:匹配項會被對映到同一個雜湊桶。

分為兩步驟:

  1. 構建雜湊表:對R表採用雜湊函式\(h_1\)進行雜湊,得到雜湊表,包含不同的雜湊桶(可以採用不同的雜湊表,但是鏈式雜湊最符合需求)。
  2. 探測:把S表元組用雜湊函式\(h_1\)進行雜湊,得到對應的雜湊桶位置,然後在雜湊桶中尋找匹配項。

image-20241115142931397

最佳化措施:布隆過濾器。

建立雜湊表時順帶構建布隆過濾器,探測階段先走布隆過濾器再走雜湊桶。

image image

存在的問題i:該演算法需要保證雜湊表能存在記憶體中,如果雜湊表太大導致無法存到記憶體中,需要不斷地換入換出,影響效率。但不幸的是,大部分情況下,我們都不能保證記憶體能完全存下雜湊表。

Partition Hash Join

基本思想:把兩個表分別用同一個雜湊函式雜湊,相同雜湊桶之間進行配對,如果雜湊桶都存不下,就再雜湊一次,直到能存下為止。

image-20241115144711876

讀取對應的雜湊桶到記憶體中配對即可。

Partition Cost:\(2(M+N)\) 【讀取資料+雜湊桶落盤(雜湊空間複雜度為\(O(n)\))】

Probe Cost:\(M+N\)

Total Cost:\(3(M+N)\)

總結

Algorithm IO Cost Example
Naïve Nested Loop Join M + (m * N) 1.3 hours
Block Nested Loop Join M + (⌈M / (B-2)⌉ * N) 0.55 seconds
Index Nested Loop Join M + (m * C) Variable
Sort-Merge Join M + N + sort cost 0.75 seconds
Hash Join 3 * (M + N) 0.45 seconds

結論:選擇Partition Hash Join,出現下述情況時使用Sort-Merge Join:

  • 資料偏斜嚴重:Hash Join退化為Sort-Merge Join

  • 資料本身需要被排序:此時Sort-Merge Join只需要額外付出 \(M+N\) 即可實現Join

一般資料庫中,Hash Join和Sort-Merge Join都會實現。

相關文章