1.****** nested-loop join:
如下圖,r為驅動表,s為匹配表,可以看到從r中分別取出r1、r2、......、rn去匹配s表的左右列,然後再合併資料,對s表進行了rn次訪問,對資料庫開銷大
2.index nested-loop join(索引巢狀):
這個要求非驅動表(匹配表s)上有索引,可以通過索引來減少比較,加速查詢。
在查詢時,驅動表(r)會根據關聯欄位的索引進行查詢,擋在索引上找到符合的值,再回表進行查詢,也就是只有當匹配到索引以後才會進行回表查詢。
如果非驅動表(s)的關聯健是主鍵的話,效能會非常高,如果不是主鍵,要進行多次回表查詢,先關聯索引,然後根據二級索引的主鍵id進行回表操作,效能上比索引是主鍵要慢。
如果有索引,會選取第二種方式進行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。
假設兩張表a 和 b:
a結構:
comments_id bigint(20) p
for_comments_if mediumint(9)
product_id int(11)
order_id int(11)
...
b結構:
id int(11) p
comments_id bigint(20)
product_id int(11)
...
其中b的關聯有comments_id,所以有索引。
join:
select * from a gc
join b gcf on gc.comments_id=gcf.comments_id
where gc.comments_id =2056
使用的是index nested-loop join,先對驅動表a的主鍵篩選,得到一條,然後對非驅動表b的索引進行seek匹配,預計得到一條資料。
下面這種情況沒用到索引:
select * from a gc
join b gcf on gc.order_id=gcf.product_id
使用block nested-loop join,如果b表資料少,作為驅動表,將b的需要的資料快取到join buffer中,批量對a表掃瞄
left join:
select * from a gc
left join b gcf on gc.comments_id=gcf.comments_id
這裡用到了索引,所以會採用index nested-loop join,因為沒有篩選條件,會選擇一張表作為驅動表去進行join,去關聯非驅動表的索引。
如果加了條件:
select * from b gcf
left join a gc on gc.comments_id=gcf.comments_id
where gcf.comments_id =2056
就會從驅動表篩選出一條來進行對非驅動表的匹配。
left join:會保全左表資料,如果右表沒相關資料,會顯示null
fight join:會保全右表資料,如果左表沒相關資料,會顯示null
inner join:部分主從表,結果會取兩個表針對on條件相匹配的最小集
mysql的join連線查詢
join 聯合查詢。查詢的結果左右連線。連成一張大表。場景 一張表裡面的資訊不能滿足我們的條件這時候可以把有關聯的表連線起來。方便查詢。別名 分為表別名和列別名。因為有些資料表的表名很長並且會用很多次所以我們可以給它起乙個簡單的別名,簡便而且 也少。列別名主要是有相同欄位時可以加以區分。例如需要從兩...
mysql各種join連線查詢
注意點 在join操作中的 on where 應該放哪些條件 目前理解 on 後放2表關聯部分 where後放最終資料篩選部分 1.下圖為各種join操作的圖表解釋及sql語句 2.自測 建表資料結果如下 可以根據圖表中的sql 語句進行相關join查詢測試 3.簡單測試2個結果 測試第乙個join...
Mysql 的連線(join)和子查詢
連線 join 和子查詢 子查詢一般是將查詢出來的結果作為其他查詢的結果使用。例如,我們要將客戶基本資訊表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售資訊表中將所有發出訂單的客戶id取出來,然後將結果傳遞給主查詢,如下所示 delete from customerinfo where cus...