MYSQL(06)-JOIN優(yōu)化

JOIN查詢(xún)?cè)?br> 如果有兩張數(shù)據(jù)結(jié)構(gòu)一樣的表(id-主鍵) ,(a有索引) ,(b無(wú)索引)。其中表t1(100條數(shù)據(jù)) 和t2(1000條數(shù)據(jù)),他們做join查詢(xún)的時(shí)候,內(nèi)部執(zhí)行的原理是什么呢?

INLJ-(Index Nested-Loop Join)

// 使用straight_join表示,固定指定 t1是驅(qū)動(dòng)表,t2是被驅(qū)動(dòng)表,防止優(yōu)化器優(yōu)化
select * from t1 straight_join t2 on (t1.a=t2.a);
  • 1.從表t1中讀取一行數(shù)據(jù)R
  • 2.從R中取出字段a去t2中查找
  • 3.取出t2中滿(mǎn)足要求的數(shù)據(jù),和R合并組成結(jié)果集中的一條數(shù)據(jù)
  • 4.重復(fù)1到3的步驟,流程圖如下

上述因?yàn)楸或?qū)動(dòng)表中使用了索引故,該join方法我們稱(chēng)之為(NLJ),這個(gè)流程中。對(duì)于表t1掃描的全表,故掃描了100行。對(duì)于表t2因?yàn)樽吡怂饕臉?shù)搜索,故t2表也是掃描了100行,索引這個(gè)join操作執(zhí)行了200次掃描。這時(shí)如果反過(guò)來(lái)t2作為驅(qū)動(dòng)表,則需要掃描2000次數(shù)據(jù),故使用NLJ的時(shí)候,盡量使用小表作為驅(qū)動(dòng)表

試想以下,如果上述t2沒(méi)有使用索引,那么t1查詢(xún)出的R對(duì)應(yīng)查詢(xún)t2的數(shù)據(jù)時(shí),每次都要全表遍歷1000次,那么查詢(xún)的次數(shù)就要達(dá)到,100*1000=10W次查詢(xún)了,這種查詢(xún)方法叫做Simple Nested-Loop Join(SNLJ),因?yàn)樾蕦?shí)在太低,所以mysql根本沒(méi)有使用這種方法。而是使用的Block Nested-Loop Join

BNLJ (Block Nested-Loop Join)

對(duì)于t1的數(shù)據(jù)并沒(méi)有一條條讀取,而是將t1的數(shù)據(jù)一次性加載到j(luò)oin_buffer的緩存中,然后掃描表t2與join_buffer中的每條數(shù)據(jù)做比對(duì),最終一共掃描數(shù)據(jù)的次數(shù)是100+1000=1100次,大大增加了效率



不過(guò)join_buffer 的內(nèi)存是有限的,如果join_buffer中放不下t1的表的所有數(shù)據(jù),那么他會(huì)將數(shù)據(jù)分幾次來(lái)放,所以驅(qū)動(dòng)表t1的數(shù)據(jù)越小,分的次數(shù)也就越小,查詢(xún)的效率就會(huì)越高
從上訴的BLJ還是NLJ算法得知,驅(qū)動(dòng)表盡可能的要使用小表,但是什么數(shù)據(jù)條數(shù)少的表就是小表么?

案例一:

對(duì)于上面的數(shù)據(jù),我們執(zhí)行以下語(yǔ)句

select * from t1 straight_join t2 on(t1.b=t2.b) where t2.id<50
select * from t2 straight_join t1 on(t1.b=t2.b) where t2.id<50

這時(shí),t2增加了where條件,那么t2作為驅(qū)動(dòng)表,加載到j(luò)oin_buffer中的大小則只有50條,這時(shí)t2才是小表

案例二:

select t1.id ,t2.* from t1 straight_join t2 on(t1.b=t2.b) where t1.id<100 and t2.id < 100
select t1.id ,t2.* from t2 straight_join t1 on(t1.b=t2.b) where t1.id<100 and t2.id < 100

這時(shí),t1 和t2都增加了where條件,條數(shù)都是100條,但是t1只查詢(xún)了id列,所以這時(shí)t1是小表

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • --- layout: post title: "如果有人問(wèn)你關(guān)系型數(shù)據(jù)庫(kù)的原理,叫他看這篇文章(轉(zhuǎn))" date...
    藍(lán)墜星閱讀 919評(píng)論 0 3
  • MySQL技術(shù)內(nèi)幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創(chuàng)始人之一Monty分支的一個(gè)版...
    沉默劍士閱讀 2,649評(píng)論 0 3
  • 目錄[TOC] MySQL的join到底能不能用 經(jīng)常聽(tīng)到2種觀點(diǎn) join性能低,盡量少用 多表join時(shí),變?yōu)?..
    xcrossed閱讀 599評(píng)論 0 4
  • 得知室友有一個(gè)半自動(dòng)咖啡機(jī)后,今日終于見(jiàn)證了自制咖啡的全過(guò)程。首先把咖啡豆放入容器里,自動(dòng)攪拌研磨后放入空置的小瓶...
    Little_Fairy66閱讀 2,693評(píng)論 0 1
  • 2015年在心里種下了一顆種子 2016年7月10日那個(gè)給我自己的約定,來(lái)一次說(shuō)走就走的旅行,只有我自己 2018...
    鄧艷芝Rita閱讀 723評(píng)論 0 1

友情鏈接更多精彩內(nèi)容