小表驅動大表
準備兩站表:
create
table
`student`
(`id`
int(11)
notnull,`
no`varchar(20
)default
null
,`name`
varchar(20
)default
null
,primary
key(
`id`))
engine
=innodb
default
charset
=utf8mb4;
insert
into student values(1
,'0001'
,'tom');
insert
into student values(2
,'0002'
,'jerry');
insert
into student values(3
,'0003'
,'acton');
create
table
`score`
(`id`
int(11)
notnull,`
no`varchar(20
)default
null
,`chinese`
double(4
,0)default
null
,`math`
double(4
,0)default
null
,`engilsh`
double(4
,0)default
null
,primary
key(
`id`))
engine
=innodb
default
charset
=utf8mb4;
insert
into score values(1
,'0001',70
,80,90
);insert
into score values(4
,'0004',11
,22,33
);
連線查詢中的驅動表與被驅動表:
當連線查詢沒有where條件時,左連線查詢中,前面的表是驅動表,後面的表是被驅動表;右連線查詢則相反;內連線查詢中,哪張表的資料比較少,哪張表就是驅動表。
當連線查詢有where條件時,在對最終結果沒有影響的前提下,優先選擇結果集最小的那張表作為驅動表。
第一種情況:(student 3條資料,score 2條資料)
#左連線
explain
select
*from student s1 left
join score s2 on s1.
no= s2.
no;
驅動表為前面的,即student:
#右連線
explain
select
*from student s1 right
join score s2 on s1.
no= s2.
no;
驅動表為後面的,即score:
#內連線
explain
select
*from student s1 inner
join score s2 on s1.
no= s2.
no;
驅動表為資料少的,即score:
第二種情況,加上where條件:
#where在score上,左外連線
explain
select
*from student s1 left
join score s2 on s1.
no= s2.
nowhere s2.no=
1;
#where在score上,右外連線
explain
select
*from student s1 right
join score s2 on s1.
no= s2.
nowhere s2.no=
1;
#內連線,where加在student上
explain
select
*from student s1 inner
join score s2 on s1.
no= s2.
nowhere s1.no=
1;
連線查詢優化
****** nested-loop join algorithms (簡單巢狀迴圈連線演算法):
for
(row1 : 驅動表)
}}
index nested-loop join algorithms (索引巢狀迴圈連線演算法):
for
(row1 : 驅動表)
block nested-loop join algorithm(基於塊的連線巢狀迴圈演算法):
其實很簡單就是把一行變成了一批,塊巢狀迴圈(bnl) 巢狀演算法使用對在外部迴圈中讀取的行進行緩衝,以減少必須讀取內部迴圈中的表的次數。例如,如果將10行讀入緩衝區並將緩衝區傳遞到下乙個內部迴圈,則可以將內部迴圈中讀取的每一行 與緩衝區中的所有10行進行比較。這將內部表必須讀取的次數減少了乙個數量級。
mysql連線緩衝區大小通過這個引數控制: join_ buffer_ size
mysql連線緩衝區有一些特徵,只有無法使用索引時才會使用連線緩衝區;聯接中只有感興趣的列儲存在其聯接緩衝區中,而不是整個行;為每個可以緩衝的連線分配乙個緩衝區,因此可以使用多個連線緩衝區來處理給定查詢;在執行連線之前分配連線緩衝區,並在查詢完成後釋放連線緩衝區。
所以查詢時最好不要把*作為查詢的字段,而是需要什麼字段查詢什麼字段,這樣緩衝區能夠緩衝足夠多的行。
演算法的優先順序:
第一種演算法忽略,mysql不會採用這種的,當我們對被驅動表建立了索引,那麼mysql一定使用的第二種演算法,當我們沒有建立索引或者對驅動表建立了索引,那麼mysql一定使用第三種演算法。
mysql 大表 驅動 MySQL小表驅動大表
在了解之前要先了解對應語法 in 與 exist。in後的括號的表示式結果要求先輸出一列字段。與之前的搜尋字段匹配,匹配到相同則返回對應行。mysql的執行順序是先執行子查詢,然後執行主查詢,用子查詢的結果按條匹配主查詢。exist後的括號裡則無輸出要求,exist判斷後面的結果集中有沒有行,有行則...
小表驅動大表
類似迴圈巢狀。for int i 5 如果小的迴圈在外層,對於資料庫連線來說就只連線5次,進行5000次操作,如果1000在外,則需要進行1000次資料庫連線,從而浪費資源,增加消耗。這就是為什麼要小表驅動大表。在tb dept bigdata表中插入100條資料,在tb emp bigdata表中...
MySQL高階知識 小表驅動大表
當b表的資料集必須小於a表的資料集時,用in優於exists select from a where id in select id from b 當a表的資料集小於b表的資料集時,用exists優於in select from a where exists select 1 from b wher...