1. 程式人生 > >MySQL 有幾種Join,其底層實現原理是什麼?

MySQL 有幾種Join,其底層實現原理是什麼?

640?wx_fmt=gif

mysql只支援一種join演算法:Nested-Loop Join(巢狀迴圈連線),但Nested-Loop Join有三種變種:

原理:

1.Simple Nested-Loop Join

如下圖,r為驅動表,s為匹配表,可以看到從r中分別取出r1、r2、......、rn去匹配s表的左右列,然後再合併資料,對s表進行了rn次訪問,對資料庫開銷大

640?wx_fmt=other

2.Index Nested-Loop Join(索引巢狀):

這個要求非驅動表(匹配表s)上有索引,可以通過索引來減少比較,加速查詢。

在查詢時,驅動表(r)會根據關聯欄位的索引進行查詢,擋在索引上找到符合的值,再回表進行查詢,也就是隻有當匹配到索引以後才會進行回表查詢。

如果非驅動表(s)的關聯健是主鍵的話,效能會非常高,如果不是主鍵,要進行多次回表查詢,先關聯索引,然後根據二級索引的主鍵ID進行回表操作,效能上比索引是主鍵要慢。

640?wx_fmt=other

3.Block Nested-Loop Join:

如果有索引,會選取第二種方式進行join,但如果join列沒有索引,就會採用Block Nested-Loop Join。

可以看到中間有個join buffer緩衝區,是將驅動表的所有join相關的列都先快取到join buffer中,然後批量與匹配表進行匹配,將第一種多次比較合併為一次,降低了非驅動表(s)的訪問頻率。

預設情況下join_buffer_size=256K,在查詢的時候MySQL會將所有的需要的列快取到join buffer當中,包括select的列,而不是僅僅只快取關聯列。在一個有N個JOIN關聯的SQL當中會在執行時候分配N-1個join buffer。

640?wx_fmt=other

例項:

假設兩張表a 和 b

640?wx_fmt=png

其中b的關聯有comments_id,所以有索引。

1.join

640?wx_fmt=png

使用的是Index Nested-Loop Join,先對驅動表a的主鍵篩選,得到一條,然後對非驅動表b的索引進行seek匹配,預計得到一條資料。

下面這種情況沒用到索引:

640?wx_fmt=png

使用Block Nested-Loop Join,如果b表資料少,作為驅動表,將b的需要的資料快取到join buffer中,批量對a表掃描

2.left join:

640?wx_fmt=png

這裡用到了索引,所以會採用Index Nested-Loop Join,因為沒有篩選條件,會選擇一張表作為驅動表去進行join,去關聯非驅動表的索引。

如果加了條件

640?wx_fmt=png

就會從驅動表篩選出一條來進行對非驅動表的匹配。

left join:會保全左表資料,如果右表沒相關資料,會顯示null

fight join:會保全右表資料,如果左表沒相關資料,會顯示null

inner join:部分主從表,結果會取兩個錶針對on條件相匹配的最小集

號外:

全國地圖poi資料下載 http://www.poi58.com

如欲購買請聯絡:

                        qq:3206833648 

                        微信:chuxinabc123