Hash join演算法原理(轉)
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,就是動態角色互換,這個動態角色互換髮生在除第一對分割槽以外的分割槽上面。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-242350/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫實現原理#4(Hash Join)資料庫
- Mysql join 的本質,Nested Loop Join 和 Hash JoinMySqlOOP
- [20180705]關於hash join 2.txt
- mysql left join轉inner joinMySql
- hash join構建點陣圖的理解
- 多表連線的三種方式詳解 hash join、merge join、 nested loopOOP
- Hash演算法演算法
- [20200306]hash join會提前終止掃描嗎.txt
- 一致性hash演算法原理及go實現演算法Go
- cmu15545筆記-Join演算法(Join Algorithms)筆記演算法Go
- [20180713]關於hash join 測試中一個疑問.txt
- flinkSql join redis的hash結構維表簡單實現SQLRedis
- 【轉】什麼是一致性hash演算法?(詳解)演算法
- 併發程式設計 join原理程式設計
- 談談fork/join實現原理
- RSA加密原理&密碼學&HASH加密密碼學
- MySQL Join的底層實現原理MySql
- consistent hash 原理,優化及實現優化
- 20200909]為什麼執行計劃不是出現hash join semi.txt
- 從Hash Join的執行計劃的細節中能看到點啥
- 前端路由原理之 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 生成演算法演算法
- perl的hash轉json後按key排序JSON排序
- MySQL中的Join 的演算法(NLJ、BNL、BKA)MySql演算法
- 一致性Hash的原理與實現
- JavaScript陣列與字串相互轉換 join、splitJavaScript陣列字串
- 強一致性hash實現java版本及強一致性hash原理Java
- 短連結演算法實現–加鹽hash演算法