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