最近有兩篇MySQL大咖級人物的文章引發了小夥伴們的關注,文章內容是關於MySQL的hash join功能。hash join看起來不夠智能,因而我打算一探究竟,看看是否能發現些端倪,文末解釋了大咖們的關注點。mysql
MySQL的hash join功能是在8.0.18版本正式推出的,最初的功能僅支持inner join,其它鏈接類型也即將支持。(空口無憑,有圖爲證!)算法
https://dev.mysql.com/worklog/sql
在這裏簡單的介紹一下MySQL的hash join 在各類鏈接類型的實現方法。ide
構建階段:從須要進行鏈接的兩個表中指定一個爲「構建」表,該表讀入內存生成哈希表,經過表的鏈接屬性計算哈希值。例如:函數
SELECT * FROM t1 JOIN t2 on (t1.id = t2.id); 假設指定t1爲構建表,則使用t1.id計算哈希值。性能
探測階段:鏈接中另外的表做爲探測階段的輸入使用,經過該表的鏈接屬性計算哈希值(使用t2.id),每行數據使用其哈希值到內存中的哈希表進行查找,若是匹配記錄,則輸出結果。優化
使用經典算法要求構建表所有讀入內存中,若是不能所有讀入內存,將會分屢次讀入,會致使探測階段產生屢次讀入操做。所以經典算法不是十分理想。ui
Inner non equi-join: 使用哈希鏈接執行該類查詢,將會對兩個鏈接表進行交叉鏈接,以後使用條件做爲過濾。blog
Semijoin: 使用哈希鏈接執行,將會利用子查詢部分做爲構建表,經過鏈接屬性計算哈希值,而後使用外部查詢的鏈接屬性的哈希值進行匹配,輸出匹配的結果。內存
Antijoin: 與Semijoin很是類似,不一樣的是輸出不匹配結果。
Left outer join: 左鏈接右側的表爲構建表。使用鏈接屬性計算哈希值,而後使用左側表的鏈接屬性計算哈希值,到哈希表內進行查找,若是匹配,輸出鏈接記錄,不然輸出NULL。
Right outer join: 執行方式與左鏈接相反。
hash join能用嗎?使用效果如何?從不少人的試用反饋來看,使用hash join對比以前的查詢性能大幅提升,但某些狀況下會產生資源過分消耗的現象,緣由在於,目前優化器尚未對hash join部分進行修改,仍舊將其視爲BNL。所以出現了一些不理想的優化狀態,這個問題將會在將來的工做中解決。目前能夠參照葉金榮老師的文章建議。
https://mp.weixin.qq.com/s/gYledARCZHvrlnCEmh2mtw
歡迎各位小夥伴試用hash join,並反饋結果。讓咱們一塊兒期待下一個版本的推出!