新聞中心
mysql join 誰(shuí)是驅(qū)動(dòng)表
首先,MySql join連接可以連接兩張或更多的數(shù)據(jù)表,但是并沒(méi)有誰(shuí)是“驅(qū)動(dòng)表”之說(shuō)。
創(chuàng)新互聯(lián)主要從事成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)柳州,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18980820575
Join分為"inner join"內(nèi)連接和"outer join"外連接兩種形式,外連接還可以進(jìn)一步分為左連接和右連接。
內(nèi)連接(inner join)只輸出被連接的表它們的關(guān)聯(lián)字段擁有交集的那些記錄行,沒(méi)交集的記錄行將被剔除掉。
外連接(left join左連接/right join右連接):
"left join" 輸出左表所有的記錄行和右表之間關(guān)聯(lián)字段擁有交集的記錄行,對(duì)于右表找不到對(duì)應(yīng)記錄行的,數(shù)據(jù)庫(kù)引擎會(huì)將空值Null賦值到右表的各個(gè)字段里。
"right join"的情況則于"left join" 剛好相反。
"inner join"——只輸出表之間存在交集的那些記錄行;
"left join" ——輸出左表所有的記錄行以及右表與之有交集的記錄行,右表找不到對(duì)應(yīng)
記錄的,數(shù)據(jù)庫(kù)引擎則將Null賦值到右表的各個(gè)字段;
"right join"——輸出右表所有的記錄行以及左表與之有交集的記錄行,左表找不到對(duì)應(yīng)
記錄的,數(shù)據(jù)庫(kù)引擎則將Null賦值到左表的各個(gè)字段;
13.MySQL聯(lián)表查詢(xún)中的驅(qū)動(dòng)表,優(yōu)化查詢(xún),以小表驅(qū)動(dòng)大表
=========================總結(jié)===========================
1.開(kāi)啟慢查詢(xún)?nèi)罩荆O(shè)置閥值,比如超過(guò)5秒就是慢SQL,并把它抓取出來(lái)。
2.explain+慢SQL 分析
3.show profile 查詢(xún)SQL在MySQL服務(wù)器里面的執(zhí)行細(xì)節(jié)和聲明周期。
MySQL表連接之驅(qū)動(dòng)表與被驅(qū)動(dòng)表
眾所周知, MySQL的驅(qū)動(dòng)表與被驅(qū)動(dòng)表是優(yōu)化器自動(dòng)優(yōu)化選擇的結(jié)果 (與表連接的前后順序等無(wú)關(guān)),我們可以用explain執(zhí)行計(jì)劃來(lái)知曉:
如上所示,前面一行t1是驅(qū)動(dòng)表,后面一行t2是被驅(qū)動(dòng)表。那么驅(qū)動(dòng)表與被驅(qū)動(dòng)表的選擇是否有規(guī)律可循呢?下面是百度搜索兩個(gè)主流的博文對(duì)驅(qū)動(dòng)表與被驅(qū)動(dòng)表的闡釋?zhuān)?/p>
1. MySQL連接查詢(xún)驅(qū)動(dòng)表被驅(qū)動(dòng)表以及性能優(yōu)化 - 阿偉~ - 博客園 博文A 主要結(jié)論:
2. mysql驅(qū)動(dòng)表與被驅(qū)動(dòng)表及join優(yōu)化_java小小小黑的博客-CSDN博客_mysql驅(qū)動(dòng)表和被驅(qū)動(dòng)表 博文B 其主要結(jié)論:
兩個(gè)帖子的結(jié)論是都差不多,而且還給出了例子來(lái)佐證。那么網(wǎng)上的結(jié)論是否權(quán)威?是否有普遍性?是否存在缺陷?
讓我們來(lái)一起打破砂鍋問(wèn)到底。下面有兩張表結(jié)構(gòu)一模一樣的表t1,t2:其中t1 100條數(shù)據(jù),t2 1000條數(shù)據(jù);t1(t2)結(jié)構(gòu)如下:
按照上面博文的結(jié)論,left join左邊是t2表,應(yīng)該是驅(qū)動(dòng)表。我們查看下結(jié)果:
與 博文B 中觀(guān)點(diǎn)1相違背(同理觀(guān)點(diǎn)2也違背),與實(shí)際不符,但究竟這是為什么呢?
下面發(fā)一張MySQL的執(zhí)行過(guò)程(來(lái)源于《MySQL實(shí)戰(zhàn)45講》中01講【一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的】)
so die si ne,原來(lái)sql執(zhí)行的過(guò)程是這樣呀。等等,不對(duì),這跟剛才SQL又有什么關(guān)系,上面left join中t2表還是左邊的呀。
我們知道MySQL高版本的性能越來(lái)越好,它是不斷進(jìn)行優(yōu)化迭代的。遠(yuǎn)古的mysql版本可能還需要人工把小表放在前面,大表放在后面等這些需要人工調(diào)優(yōu)的經(jīng)驗(yàn)早就已經(jīng)被解決了。也就是說(shuō)我們寫(xiě)的語(yǔ)句,MySQL為了追求更好的效率,它在執(zhí)行器執(zhí)行前已經(jīng)幫我們優(yōu)化了。那么實(shí)際優(yōu)化后的sql如何查看呢?用show warning命令:
其中Message就是優(yōu)化后實(shí)際執(zhí)行的sql語(yǔ)句,格式化后如下:
優(yōu)化后left join左連接變成了內(nèi)連接(inner) join。所以用優(yōu)化后的sql看,表t1是小表所以作為驅(qū)動(dòng)表,與實(shí)際結(jié)果相符。
left join 竟然優(yōu)化成了join,太神奇了,但這是為什么呢?原因在于mysql中null與任何值做等值或者不等值比較的時(shí)候都是null,即使是select null=null 也是null。這樣where 條件t1.a=t2.a查詢(xún)條件不會(huì)包含t2.a為NULL的行,實(shí)際效果其實(shí)跟join一樣,被優(yōu)化器智能的優(yōu)化了。
我們直接看執(zhí)行計(jì)劃看實(shí)際結(jié)果吧:
結(jié)果顯示t2是驅(qū)動(dòng)表,t1是被驅(qū)動(dòng)表。t2是1000條數(shù)據(jù)按理說(shuō)是大表應(yīng)該是被驅(qū)動(dòng)表,與 博文A , 博文B 的結(jié)論又不一致了。
《MySQL實(shí)戰(zhàn)45講》中34講【到底可不可以使用join】已經(jīng)講的很透徹了,很深入了,我就不在這里獻(xiàn)丑了。啰嗦幾句大概就是驅(qū)動(dòng)表是全表掃描不走索引,所以選被驅(qū)動(dòng)表t1可以走索引,不會(huì)全表掃描,減少I(mǎi)O次數(shù),性能高。里面對(duì)大表小表的總結(jié),簡(jiǎn)直是精髓,特意在此再次著重強(qiáng)調(diào):
在決定哪個(gè)表做驅(qū)動(dòng)表的時(shí)候,應(yīng)該是兩個(gè)表按照各自的條件過(guò)濾,過(guò)濾完成之后,計(jì)算參與join的各個(gè)字段的總數(shù)據(jù)量,數(shù)據(jù)量小的那個(gè)表,就是“小表”,應(yīng)該作為驅(qū)動(dòng)表。
按照上面分析,我們先獨(dú)立思考下MySQL會(huì)選擇哪張表作為驅(qū)動(dòng)表呢?
表t1,t2在字段a上都有索引不會(huì)全表掃描,其中t1.a=5條件過(guò)濾后只有一條,很顯然嘛,t1數(shù)據(jù)量少是小表,肯定是驅(qū)動(dòng)表,錯(cuò)不了,再說(shuō)了前面的紅色粗體已經(jīng)強(qiáng)調(diào)了,不會(huì)有錯(cuò)的。
有冇搞錯(cuò)?事實(shí)又被打臉了。還記得在開(kāi)篇我們說(shuō)過(guò)的mysql優(yōu)化器會(huì)對(duì)sql語(yǔ)句進(jìn)行優(yōu)化的嗎?下面我們看下執(zhí)行計(jì)劃與優(yōu)化的sql語(yǔ)句:
格式化后的優(yōu)化SQL如下:
優(yōu)化后兩表t1,t2都走索引,并且都只有一條結(jié)果返回,因此都只會(huì)掃描一行,數(shù)據(jù)量一樣,所以誰(shuí)在前面誰(shuí)就是驅(qū)動(dòng)表,也就是上面sql中表t2。一切都釋然,豁然開(kāi)通!
回頭再仔細(xì)想想,高,實(shí)在是高!仔細(xì)深思之后MySQL優(yōu)化后的句子真讓人猛拍大腿。高明之處在于:
1. 本來(lái)join連接是個(gè)M*N的嵌套循環(huán),優(yōu)化后變成了M+N的判斷,兩表不再嵌套判斷了。
2. 優(yōu)化后,兩表沒(méi)有多大必然聯(lián)系,只需把兩表的結(jié)果集拼接即可,互不干擾。如果mysql未來(lái)可以多線(xiàn)程查詢(xún),豈不十分快哉!
小伙伴們還記得我們?cè)谏弦徽? MySQL索引初探 中編碼類(lèi)型不一致發(fā)生隱式轉(zhuǎn)換時(shí)有時(shí)候走索引,有時(shí)候索引又失效的問(wèn)題嗎?下面我們選取有代表性的一條記錄來(lái)分析:
其中表demo_test總共有640條數(shù)據(jù),demo_test_ass有3條數(shù)據(jù)。顯然經(jīng)過(guò)過(guò)濾條件t.rid1完成后demo_test_ass數(shù)據(jù)量小,應(yīng)該作為驅(qū)動(dòng)表。雖然test.c_utf8mb4 = t.c2兩字段連接中發(fā)生了t.c2字段發(fā)生隱式轉(zhuǎn)換,但是實(shí)際上并不影響被驅(qū)動(dòng)表test上的c_utf8mb4索引。
好了,本章到此結(jié)束,讓我們一起 總結(jié)一下MySQL驅(qū)動(dòng)表與被驅(qū)動(dòng)表的選取原則 :
?? ? 同等條件,優(yōu)先選取有索引的表作為被驅(qū)動(dòng)表。 在此介紹一下什么叫同等條件,比如上面的②中的語(yǔ)句。 兩表沒(méi)有其他額外的過(guò)濾條件,因此選關(guān)聯(lián)字段有索引的t1作為被驅(qū)動(dòng)表。但是如果加了條件(and t1.id=3),此時(shí)t1數(shù)據(jù)量少,就選取了t2作為被驅(qū)動(dòng)表。
??? MySQL選擇驅(qū)動(dòng)表與被驅(qū)動(dòng)表是基于優(yōu)化器優(yōu)化后的,小表是驅(qū)動(dòng)表,大表是被驅(qū)動(dòng)表。 基于優(yōu)化器優(yōu)化后開(kāi)篇的 博文A與B 結(jié)論成立。
當(dāng)然這都是我一家之言,并不是官方結(jié)論,目前暫未找到官方確切對(duì)于驅(qū)動(dòng)表與被驅(qū)動(dòng)表的解釋?zhuān)?qǐng)大家踴躍拍磚!
當(dāng)前名稱(chēng):mysql驅(qū)動(dòng)表怎么查 mysql驅(qū)動(dòng)程序lib在哪找
URL地址:http://ef60e0e.cn/article/doecjgh.html