閱讀這篇文章,你將會了解
1.什麼是Nested-Loop Join?
2.Index Nested-Loop Join怎麼優化連接?
3.Block Nested-Loop Join怎麼優化連接?
一.Nested-Loop Join
在Mysql中,使用Nested-Loop Join的算法思想去優化join,Nested-Loop Join翻譯成中文則是“嵌套循環連接”。
舉個例子:
select * from t1 inner join t2 on t1.id=t2.tid
(1)t1稱爲外層表,也可稱爲驅動表。
(2)t2稱爲內層表,也可稱爲被驅動表。
//僞代碼表示:
List<Row> result = new ArrayList<>();
for(Row r1 in List<Row> t1){
for(Row r2 in List<Row> t2){
if(r1.id = r2.tid){
result.add(r1.join(r2));
}
}
}
在Mysql的實現中,Nested-Loop Join有3種實現的算法:
- Simple Nested-Loop Join:SNLJ,簡單嵌套循環連接
- Index Nested-Loop Join:INLJ,索引嵌套循環連接
- Block Nested-Loop Join:BNLJ,緩存塊嵌套循環連接
在選擇Join算法時,會有優先級,理論上會優先判斷能否使用INLJ、BNLJ:
Index Nested-LoopJoin > Block Nested-Loop Join > Simple Nested-Loop Join
二.Simple Nested-Loop
- 簡單嵌套循環連接實際上就是簡單粗暴的嵌套循環,如果table1有1萬條數據,table2有1萬條數據,那麼數據比較的次數=1萬 * 1萬 =1億次,這種查詢效率會非常慢。
- 所以Mysql繼續優化,然後衍生出Index Nested-LoopJoin、Block Nested-Loop Join兩種NLJ算法。在執行join查詢時mysql會根據情況選擇兩種之一進行join查詢。
三.Index Nested-LoopJoin(減少內層表數據的匹配次數)
- 索引嵌套循環連接是基於索引進行連接的算法,索引是基於內層表的,通過外層表匹配條件直接與內層表索引進行匹配,避免和內層表的每條記錄進行比較, 從而利用索引的查詢減少了對內層表的匹配次數,優勢極大的提升了 join的性能:
原來的匹配次數 = 外層錶行數 * 內層錶行數
優化後的匹配次數= 外層表的行數 * 內層表索引的高度
- 使用場景:只有內層表join的列有索引時,才能用到Index Nested-LoopJoin進行連接。
- 由於用到索引,如果索引是輔助索引而且返回的數據還包括內層表的其他數據,則會回內層表查詢數據,多了一些IO操作。
四.Block Nested-Loop Join(減少外層表數據的循環次數)
- 緩存塊嵌套循環連接通過一次性緩存多條數據,把參與查詢的列緩存到Join Buffer 裏,然後拿join buffer裏的數據批量與內層表的數據進行匹配,從而減少了外層循環的次數。
- 當不使用Index Nested-Loop Join的時候,默認使用Block Nested-Loop Join。
- 什麼是Join Buffer?
(1)Join Buffer會緩存所有參與查詢的列而不是隻有Join的列。
(2)可以通過調整join_buffer_size緩存大小
(3)join_buffer_size的默認值是256K,join_buffer_size的最大值在MySQL 5.1.22版本前是4G-1,而之後的版本才能在64位操作系統下申請大於4G的Join Buffer空間。
(4)使用Block Nested-Loop Join算法需要開啓優化器管理配置的optimizer_switch的設置block_nested_loop爲on,默認爲開啓。
五.如何優化Join速度
- 用小結果集驅動大結果集,減少外層循環的數據量:
如果小結果集和大結果集連接的列都是索引列,mysql在內連接時也會選擇用小結果集驅動大結果集,因爲索引查詢的成本是比較固定的,這時候外層的循環越少,join的速度便越快。 - 爲匹配的條件增加索引:爭取使用INLJ,減少內層表的循環次數
- 增大join buffer size的大小:當使用BNLJ時,一次緩存的數據越多,那麼外層表循環的次數就越少
- 減少不必要的字段查詢:
(1)當用到BNLJ時,字段越少,join buffer 所緩存的數據就越多,外層表的循環次數就越少;
(2)當用到INLJ時,如果可以不回表查詢,即利用到覆蓋索引,則可能可以提示速度。(未經驗證,只是一個推論)
六.參考文檔
https://www.wengbi.com/thread_99558_1.html
https://www.cnblogs.com/starhu/p/6418842.html
https://www.cnblogs.com/starhu/p/6418833.html