mysql 第四十七篇文章~mysql優化之相關join
一簡介:參考了幾位師兄,尤其是M哥大神的博客,讓我恍然大悟,趕緊記錄下
二 原理:
mysql的三種算法
1 Simple Nested-Loop Join
將驅動表/外部表的結果集作為循環基礎數據,然後循環從該結果集每次一條獲取數據作為下一個表的過濾條件查詢數據,然後合並結果。如果有多表join,則將前面的表的結果集作為循環數據,取到每行再到聯接的下一個表中循環匹配,獲取結果集返回給客戶端。
註意點:單條記錄一條一條進行 比如C 表有N條記錄去匹配D表 M 條記錄那麽要執行 NXM次,如果多表join,那麽次數會更多
2 Block Nested-Loop Join
BNL優化,在join字段無索引的情況下
Block Nested-Loop Join對比Simple Nested-Loop Join多了一個中間處理的過程,也就是join buffer,使用join buffer將驅動表的查詢JOIN相關列都給緩沖到了JOIN BUFFER當中,然後批量與非驅動表進行比較,這也來實現的話,可以將多次比較合並到一次,降低了非驅 動表的訪問頻率。也就是只需要訪問一次S表。這樣來說的話,就不會出現多次訪問非驅動表的情況了,也只有這種情況下才會訪問join buffer。
註意點:
1 此算法並非單條記錄匹配,而是多條記錄合並一起匹配,減少了匹配次數,提高了效率
2 此優化手段是在mysql5.5+版本開始出現,默認是打開狀態
3 出現標識
explain生成解析樹後出現 Using join buffer (Block Nested Loop) 連接字段無索引,但是利用了BNL優化了語句
4 能夠被buffer的每一個join都會分配一個buffer, 也就是說一個query最終可能會使用多個join buffer
5 join buffer中只會保存參與join的列, 並非整個數據行。
6 只有在join類型為all, index, range的時候才可以使用join buffer。
3 Index Nested-Loop Join
這種算法在鏈接查詢的時候,驅動表會根據關聯字段的索引進行查找,當在索引上找到了符合的值,再回表進行查詢,也就是只有當匹配到索引以後才會進行回表。至於驅動表的選擇,MySQL優化器一般情況下是會選擇記錄數少的作為驅動表,但是當SQL特別復雜的時候不排除會出現錯誤選擇。
註意點:
1 對於驅動表和非驅動表都有索引的情況下,會加速查找速度和減少匹配次數
2 最好采用自增長主鍵進行join字段,非唯一性索引會降低查詢匹配速度,因為先要根據非唯一性索引定位主鍵,然後再進行查詢
三 相關總結:
1 多表join查詢要保證小結果集驅動大結果集作為優化選擇
2 減少回表操作和匹配次數是算法的核心思想
3 多表join查詢要保證連接join的字段都有索引
4 varchar作為主鍵進行連接查詢是無法走索引的,會出現BNL優化(要特別註意)
5 對於無法走索引的join查詢建議拆分或者更改條件
6 對於order by所選擇的字段要盡量選用驅動表帶索引字段
四 核心的東西來源於M哥的博客
mysql 第四十七篇文章~mysql優化之相關join