MySQL的Hash Join能用嗎?

MySQL的Hash Join能用嗎?

最近有兩篇MySQL大咖級人物的文章引發了小夥伴們的關注,文章內容是關於MySQL的hash join功能。hash join看起來不夠智能,因而我打算一探究竟,看看是否能發現些端倪,文末解釋了大咖們的關注點。mysql

MySQL的hash join功能是在8.0.18版本正式推出的,最初的功能僅支持inner join,其它鏈接類型也即將支持。(空口無憑,有圖爲證!)算法

MySQL的Hash Join能用嗎?

https://dev.mysql.com/worklog/sql

在這裏簡單的介紹一下MySQL的hash join 在各類鏈接類型的實現方法。ide

inner join:

  • Classic hash join:經典的哈希鏈接算法分爲兩個階段,構建和探測。

構建階段:從須要進行鏈接的兩個表中指定一個爲「構建」表,該表讀入內存生成哈希表,經過表的鏈接屬性計算哈希值。例如:函數

SELECT * FROM t1 JOIN t2 on (t1.id = t2.id); 假設指定t1爲構建表,則使用t1.id計算哈希值。性能

探測階段:鏈接中另外的表做爲探測階段的輸入使用,經過該表的鏈接屬性計算哈希值(使用t2.id),每行數據使用其哈希值到內存中的哈希表進行查找,若是匹配記錄,則輸出結果。優化

使用經典算法要求構建表所有讀入內存中,若是不能所有讀入內存,將會分屢次讀入,會致使探測階段產生屢次讀入操做。所以經典算法不是十分理想。ui

  • 基於磁盤的hash join:須要將構建表和探測表分割成若干個小文件保存在磁盤上,文件的大小要保證能夠徹底讀入內存中(分割文件的算法採用與哈希表不一樣的哈希函數,目的是使相同哈希值的構建表和探測表的數據保存在同一文件內,而且數據的分佈更加均勻)。接下來的操做和經典算法的過程差很少,每次讀入一部分文件進行處理,直到全部的分割文件處理結束。

Inner non equi-join: 使用哈希鏈接執行該類查詢,將會對兩個鏈接表進行交叉鏈接,以後使用條件做爲過濾。blog

Semijoin: 使用哈希鏈接執行,將會利用子查詢部分做爲構建表,經過鏈接屬性計算哈希值,而後使用外部查詢的鏈接屬性的哈希值進行匹配,輸出匹配的結果。內存

Antijoin: 與Semijoin很是類似,不一樣的是輸出不匹配結果。

Left outer join: 左鏈接右側的表爲構建表。使用鏈接屬性計算哈希值,而後使用左側表的鏈接屬性計算哈希值,到哈希表內進行查找,若是匹配,輸出鏈接記錄,不然輸出NULL。

Right outer join: 執行方式與左鏈接相反。

MySQL的Hash Join能用嗎?

MySQL的Hash Join能用嗎?
MySQL的Hash Join能用嗎?
hash join能用嗎?使用效果如何?從不少人的試用反饋來看,使用hash join對比以前的查詢性能大幅提升,但某些狀況下會產生資源過分消耗的現象,緣由在於,目前優化器尚未對hash join部分進行修改,仍舊將其視爲BNL。所以出現了一些不理想的優化狀態,這個問題將會在將來的工做中解決。目前能夠參照葉金榮老師的文章建議。

https://mp.weixin.qq.com/s/gYledARCZHvrlnCEmh2mtw

歡迎各位小夥伴試用hash join,並反饋結果。讓咱們一塊兒期待下一個版本的推出!

相關文章
相關標籤/搜索