一、mysql inner join為什么不走索引
因為(wei)索(suo)引(yin)的(de)優(you)勢是在大(da)表(biao)(biao)中過(guo)濾出小的(de)結(jie)果集(ji)進(jin)行(xing)聯接,mysql inner join句根本沒有任(ren)何(he)過(guo)濾條件。另外表(biao)(biao)很小的(de)話(hua)全表(biao)(biao)掃描比(bi)索(suo)引(yin)快(kuai)。針對查詢語(yu)句過(guo)慢的(de)問題,首(shou)先(xian)使(shi)用explain關鍵字(zi)對sql的(de)執(zhi)行(xing)計劃進(jin)行(xing)分析。發現整(zheng)個(ge)查詢過(guo)程中均(jun)沒有使(shi)用索(suo)引(yin),每(mei)個(ge)表(biao)(biao)的(de)數據(ju)不大(da),但是三張表(biao)(biao)聯合,數據(ju)量(liang)直接乘(cheng)積(ji)量(liang)級了;
既然定位到索引問題,就去數(shu)據庫(ku)查看表的索引信息,卻發(fa)現相關(guan)字段已經建立(li)了索引,但(dan)是查詢過程中卻未使用到索引;
使(shi)用(yong)左外連接時(shi),數據(ju)庫會以左表(biao)為(wei)驅(qu)動,右表(biao)被(bei)驅(qu)動,考慮使(shi)用(yong)inner join替(ti)換(huan)left join來觀(guan)察數據(ju)庫查詢是(shi)否會進行優化,替(ti)換(huan)后使(shi)用(yong)explain發(fa)現retailer表(biao)作為(wei)了被(bei)驅(qu)動表(biao),且使(shi)用(yong)了索引,但是(shi)customer兩個表(biao)仍(reng)然未走索引,且耗時(shi)過長(chang);
經過對(dui)關聯表(biao)的結構進行深入對(dui)比,且對(dui)字段類(lei)型、長度、編(bian)碼等(deng)信息對(dui)比后發現數(shu)據表(biao)的編(bian)碼方式存在(zai)差異,retailer表(biao)中(zhong)字段字符集格式為utf8mb4,而customer表(biao)中(zhong)字符集格式為utf8;
將關聯字(zi)段(duan)字(zi)符集統(tong)一后,使用(yong)left join左外連接(jie)仍(reng)然可以很好的命中索(suo)引,查(cha)詢時間直接(jie)0.1s。
延伸閱讀:
二、InnoDB是什么
InnoDB 是 MySQL 上名(ming)列(lie)前茅個提供外(wai)鍵(jian)約(yue)束(shu)的(de)數(shu)據(ju)(ju)存儲引擎,除了提供事務處(chu)(chu)理外(wai),InnoDB 還(huan)支持行鎖,提供和 Oracle 一樣的(de)一致性(xing)的(de)不加(jia)鎖讀(du)(du)取,能(neng)增加(jia)并發讀(du)(du)的(de)用戶數(shu)量并提高性(xing)能(neng),不會增加(jia)鎖的(de)數(shu)量。InnoDB 的(de)設計目標是處(chu)(chu)理大容量數(shu)據(ju)(ju)時最大化性(xing)能(neng),它的(de) CPU 利用率是其他(ta)所有(you)基于磁盤的(de)關(guan)系數(shu)據(ju)(ju)庫(ku)引擎中最有(you)效率的(de)。
InnoDB 是一套(tao)放(fang)(fang)在 MySQL 后臺的(de)完整(zheng)數據庫(ku)系統,InnoDB 有它自己的(de)緩(huan)沖池,能緩(huan)沖數據和索引,InnoDB 還把數據和索引存(cun)放(fang)(fang)在表(biao)空間里面,可(ke)能包含好幾個文件,這和 MyISAM 表(biao)完全不同,在 MyISAM 中,表(biao)被存(cun)放(fang)(fang)在單(dan)獨的(de)文件中,InnoDB 表(biao)的(de)大(da)小只(zhi)受限于操(cao)作系統文件的(de)大(da)小,一般為(wei) 2GB。