hash連接


簡單回顧嵌套循環:

兩個表關聯,較小的表(指使用了過濾條件后結果集較小的表)稱為驅動表或者外表(,另一個稱為內表。在嵌套連接過程中,oracle首先讀取驅動表的第一條數據,然后和內表進行比對,所以匹配的記錄存放在結果集中,然后讀取驅動表的下一條數據,重復上面的操作,直到驅動表的所以數據都處理了一遍。嵌套循環是一種從連接結果中提取第一批數據的最快捷方式。

在驅動表較小、或者內表的關聯列上有唯一索引或高度可選的非唯一索引時,嵌套循環的效果一般會比較好。

在索引范圍掃描中,如果需要訪問的鍵值數超過大幾百萬時,就不建議使用索引范圍掃描了,因為此時開銷會呈幾何數增長。因此,在使用嵌套循環的過程中,如果發現需要訪問的鍵值數有大幾百萬(驅動表記錄數*每條數據與內表關聯需要訪問的鍵值數),就應該考慮使用hash連接代替,如果是單表走的索引,則應該考慮走全表掃描。

 

本次小課堂分享的內容:

1、簡單了解hash連接的流程;

2、了解hash連接的使用限制及使用場景;

 

hash連接的流程

對於什么是Hash算法原理?這個問題有點難度,不是很好說清楚,來做一個比喻吧:我們有很多的小豬,每個的體重都不一樣,假設體重分布比較平均(我們考慮到公斤級別),我們按照體重來分,划分成100個小豬圈。 然后把每個小豬,按照體重趕進各自的豬圈里,記錄檔案。 好了,如果我們要找某個小豬怎么辦呢?我們需要每個豬圈,每個小豬的比對嗎? 當然不需要了。 我們先看看要找的這個小豬的體重,然后就找到了對應的豬圈了。 在這個豬圈里的小豬的數量就相對很少了。 我們在這個豬圈里就可以相對快的找到我們要找到的那個小豬了。 對應於hash算法。 就是按照hashcode分配不同的豬圈,將hashcode相同的豬放到一個豬圈里。 查找的時候,先找到hashcode對應的豬圈,然后在逐個比較里面的小豬。 所以問題的關鍵就是建造多少個豬圈比較合適。 如果每個小豬的體重全部不同(考慮到毫克級別),每個都建一個豬圈,那么我們可以最快速度的找到這頭豬。缺點就是,建造那么多豬圈的費用有點太高了。 如果我們按照10公斤級別進行划分,那么建造的豬圈只有幾個吧,那么每個圈里的小豬就很多了。我們雖然可以很快的找到豬圈,但從這個豬圈里逐個確定那頭小豬也是很累的。 所以,好的hashcode,可以根據實際情況,根據具體的需求,在時間成本(更多的豬圈,更快的速度)和空間本(更少的豬圈,更低的空間需求)之間平衡。(摘自網絡)

 

兩個表做hash連接,較小的表作為驅動表(這里指運用了過濾條件后結果集較小的表),另一個表稱為探測表。

hash函數的一個特性:相同值經過hash函數運算得到的hash code一定相同,不同值經過hash函數運算得到的hash code可能不同。

在兩個表做hash連接的過程中,我們會對驅動表的關聯列使用兩個內置函數計算hash值,我們把這兩個hash值分別記為hash_value_1和hash_value_2,我們將hash_value_1相同的記錄存放在一個hash bucket中,這里注意hash bucket只需要記錄該sql語句的查詢列、關聯列及hash_value_2即可。hash table由這些hash bucket組成。

 

最理想模式下的hash連接流程:

optimal模式

optimal模式就是從驅動表上獲取的結果集比較小,可以把整個hash table都建立在用戶可以使用的內存區域里。

大致上分為以下幾步:

1、利用連接列上的hash函數,將從驅動表上獲取的結果集做成hash table存放在內存中,這里的hash bucket總是2的n次方。可以簡單的把hash table看做內存里的一個大正方形,里面有很多小格子,驅動表的數據就分布在這些小格子里面,這些小格子就是hash bucket。

2、oracle開始讀取探測表的數據,對每一個數據都做關聯列上的hash函數(和驅動表的hash函數相同),定位到hash table中的hash bucket,找到hash bucket就進去看看有沒有匹配的數據。

3、如果hash bucket里沒有數據,則丟棄探測表中的這一行數據。如果有,則進一步查看里面的數據是否和探測表的這條記錄匹配。

4、循環處理,直到處理完探測表中的所有記錄,返回結果集。

 

hash連接的使用限制及使用場景:

1、hash連接種驅動表的關聯列上的可選擇性應當盡可能的好(取值分布比較均勻),因為這個可選擇性會影響hash bucket中的記錄數,而hash bucket中的記錄數又會影響從從匹配數據的效率。因此一個hash bucket所包含的記錄數過多,可能嚴重降低所對應的hash連接的執行效率。

2、hash連接只適用於CBO,且只能用於等值連接。

3、hash連接很適合於一個小表(結果集)與一個大表之間的連接,特別是小表關聯列上的可選擇性非常好的情況,此時耗費的時間可以近似看成全表掃描兩個表耗費的時間。

4、當關聯列上缺乏有效的索引,hash連接比嵌套循環更加有效。

 --整理自網絡


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM