Hash join演算法原理(轉)

zhouwf0726發表於2019-07-02

Hash join演算法原理

自從oracke 7.3以來,oracle提供了一種新的join技術,就是hash joinHash Join只能用於相等連線,且只能在CBO優化器模式下。相對於nested loop joinhash join更適合處理大型結果集。Hash join不需要在驅動表上存在索引。

一. Hash Join概述

Hash join演算法的一個基本思想就是根據小的row sources(稱作build input,我們記較小的表為S,較大的表為B) 建立一個可以存在於hash area記憶體中的hash table,然後用大的row sources(稱作probe input) 來探測前面所建的hash table。如果hash area記憶體不夠大,hash table就無法完全存放在hash area記憶體中。針對這種情況,Oracle在連線鍵利用一個hash函式將build inputprobe input分割成多個不相連的分割槽(分別記作SiBi),這個階段叫做分割槽階段;然後各自相應的分割槽,即SiBi再做Hash join,這個階段叫做join階段。

如果在分割槽後,針對某個分割槽所建的hash table還是太大的話,oracle就採用nested-loops hash join。所謂的nested-loops hash join就是對部分Si建立hash table,然後讀取所有的Bi與所建的hash table做連線,然後再對剩餘的Si建立hash table,再將所有的Bi與所建的hash table做連線,直至所有的Si都連線完了。

Hash Join演算法有一個限制,就是它是在假設兩張表在連線鍵上是均勻的,也就是說每個分割槽擁有差不多的資料。但是實際當中資料都是不均勻的,為了很好地解決這個問題,oracle引進了幾種技術,點陣圖向量過濾、角色互換、柱狀圖,這些術語的具體意義會在後面詳細介紹。

二. Hash Join原理

我們用一個例子來解釋Hash Join演算法的原理,以及上述所提到的術語。

考慮以下兩個資料集。

S={1,1,1,3,3,4,4,4,4,5,8,8,8,8,10}

B={0,0,1,1,1,1,2,2,2,2,2,2,3,8,9,9,9,10,10,11}

Hash Join的第一步就是判定小表(即build input)是否能完全存放在hash area記憶體中。如果能完全存放在記憶體中,則在記憶體中建立hash table,這是最簡單的hash join

如果不能全部存放在記憶體中,則build input必須分割槽。分割槽的個數叫做fan-outFan-out是由hash_area_sizecluster size來決定的。其中cluster size等於db_block_size * hash_multiblock_io_counthash_multiblock_io_countoracle9i中是隱含引數。這裡需要注意的是fan-out並不是build input的大小/hash_ara_size,也就是說oracle決定的分割槽大小有可能還是不能完全存放在hash area記憶體中。大的fan-out導致許多小的分割槽,影響效能,而小的fan-out導致少數的大的分割槽,以至於每個分割槽不能全部存放在記憶體中,這也影響hash join的效能。

Oracle採用內部一個hash函式作用於連線鍵上,將SB分割成多個分割槽,在這裡我們假設這個hash函式為求餘函式,即Mod(join_column_value,10)。這樣產生十個分割槽,如下表。

分割槽

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

0,0,10,10

1,1,1,1,11

2,2,2,2,2,2

3

NULL

NULL

NULL

NULL

8

9,9,9

S0

10

S1

1,1,1

S2

Null

S3

3,3

S4

4,4,4,4

S5

5

S6

NULL

S7

NULL

S8

8,8,8,8

S9

NULL

經過這樣的分割槽之後,只需要相應的分割槽之間做join即可(也就是所謂的partition pairs),如果有一個分割槽為NULL的話,則相應的分割槽join即可忽略。

在將S表讀入記憶體分割槽時,oracle即記錄連線鍵的唯一值,構建成所謂的點陣圖向量,它需要佔hash area記憶體的5%左右。在這裡即為{1,3,4,5,8,10}

當對B表進行分割槽時,將每一個連線鍵上的值與點陣圖向量相比較,如果不在其中,則將其記錄丟棄。在我們這個例子中,B表中以下資料將被丟棄

{0,0,2,2,2,2,2,2,9,9,9,9,9}。這個過程就是點陣圖向量過濾。

S1,B1做完連線後,接著對Si,Bi進行連線,這裡oracle將比較兩個分割槽,選取小的那個做build input,就是動態角色互換,這個動態角色互換髮生在除第一對分割槽以外的分割槽上面。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-242350/,如需轉載,請註明出處,否則將追究法律責任。

相關文章