MySQL 小表驅動大表

2021-10-24 03:03:52 字數 3287 閱讀 9300

小表驅動大表

準備兩站表:

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...