Hash join演算法原理
自從oracke 7.3以來,oracle提供了一種新的join技術,就是hash join。Hash Join只能用於相等連線,且只能在CBO最佳化器模式下。相對於nested loop join,hash 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 input和probe input分割成多個不相連的分割槽(分別記作Si和Bi),這個階段叫做分割槽階段;然後各自相應的分割槽,即Si和Bi再做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-out。Fan-out是由hash_area_size和cluster size來決定的。其中cluster size等於db_block_size * hash_multiblock_io_count,hash_multiblock_io_count在oracle9i中是隱含引數。這裡需要注意的是fan-out並不是build input的大小/hash_ara_size,也就是說oracle決定的分割槽大小有可能還是不能完全存放在hash area記憶體中。大的fan-out導致許多小的分割槽,影響效能,而小的fan-out導致少數的大的分割槽,以至於每個分割槽不能全部存放在記憶體中,這也影響hash join的效能。
Oracle採用內部一個hash函式作用於連線鍵上,將S和B分割成多個分割槽,在這裡我們假設這個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,就是動態角色互換,這個動態角色互換髮生在除第一對分割槽以外的分割槽上面。
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18921899/viewspace-1017658/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Hash join演算法原理(轉)演算法
- 資料庫實現原理#4(Hash Join)資料庫
- Mysql join 的本質,Nested Loop Join 和 Hash JoinMySqlOOP
- [20180705]關於hash join 2.txt
- hash join構建點陣圖的理解
- 多表連線的三種方式詳解 hash join、merge join、 nested loopOOP
- Hash演算法演算法
- [20200306]hash join會提前終止掃描嗎.txt
- 一致性hash演算法原理及go實現演算法Go
- cmu15545筆記-Join演算法(Join Algorithms)筆記演算法Go
- flinkSql join redis的hash結構維表簡單實現SQLRedis
- [20180713]關於hash join 測試中一個疑問.txt
- 併發程式設計 join原理程式設計
- 談談fork/join實現原理
- RSA加密原理&密碼學&HASH加密密碼學
- MySQL Join的底層實現原理MySql
- consistent hash 原理,優化及實現優化
- 從Hash Join的執行計劃的細節中能看到點啥
- 20200909]為什麼執行計劃不是出現hash join semi.txt
- 前端路由原理之 hash 模式和 history 模式前端路由模式
- 影象相似度中的Hash演算法演算法
- 一致性hash演算法演算法
- 區塊鏈概念1:Hash演算法區塊鏈演算法
- join、inner join、left join、right join、outer join的區別
- 記錄一次 postgresql 最佳化案例( 巢狀迴圈改HASH JOIN )SQL巢狀
- 資料庫實現原理#1(Nested Loop Join)資料庫OOP
- 資料庫實現原理#3(Merge Join).md資料庫
- 大資料開發-Spark Join原理詳解大資料Spark
- 深入淺出一致性Hash原理
- MySQL LEFT JOIN/ INNER JOIN/RIGHT JOINMySql
- 分享一種最小 Perfect Hash 生成演算法演算法
- MySQL中的Join 的演算法(NLJ、BNL、BKA)MySql演算法
- 一致性Hash的原理與實現
- PHP 之一致性 hash 演算法PHP演算法
- 短連結演算法實現–加鹽hash演算法
- 一致性hash演算法的理解演算法
- 強一致性hash實現java版本及強一致性hash原理Java
- 使用模擬退火演算法優化 Hash 函式演算法優化函式
- 識別雜湊演算法型別hash-identifier演算法型別IDE