查一次left?join沒有走索引以及原因分析
查一次left join沒有走索引的原因
線上有個(gè)查詢sql,原來(lái)是inner join 查詢沒有問(wèn)題,后來(lái)應(yīng)業(yè)務(wù)要求改成left join之后, 查詢時(shí)間就暴漲了 需要長(zhǎng)達(dá)24s

通過(guò)explain分析,發(fā)現(xiàn)訂單表沒有走索引 ,分析之后解決了,記錄下來(lái)。
為了簡(jiǎn)潔起見,這里就將無(wú)關(guān)的查詢字段都用*
具體sql如下
SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 and order_type_code=00901 group by a.unique_code LIMIT 10
用explain命令分析如下

發(fā)現(xiàn)table d 的type為all, rows居然高達(dá)20萬(wàn)行 。
d對(duì)應(yīng)的表為order_detail 表,type為all 說(shuō)明并沒有走索引。
這里首先看關(guān)聯(lián)條件
from t_item_detail a left join t_order_detail d on a.order_code=d.order_code
該條件并無(wú)問(wèn)題,然后這兩張表的order_code字段是否加索引.


兩張表的order_code字段均有索引。
其次再看, 如果兩個(gè)字段或者兩張表的編碼不同,也會(huì)導(dǎo)致索引失效。
但是這兩張表的編碼和字段編碼也均相同,因此也排除掉。
最后發(fā)現(xiàn),
如果寫成
explain SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code and d.order_type_code=00901 left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 group by a.unique_code LIMIT 10
也就是將原來(lái)在where條件的order_type_code=00901 寫到left join的條件后面

d的索引就生效了,所有的索引都生效了。
查詢時(shí)間也從原來(lái)的24秒 變成了不到1秒。

這是為什么呢?
其實(shí)問(wèn)題就出在這個(gè) d.order_type_code=00901 這個(gè)條件上
當(dāng)有這個(gè)條件時(shí)候

全文掃描
沒有這個(gè)條件的時(shí)候

從sql的執(zhí)行順序來(lái)分析:
SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 and order_type_code=00901 group by a.unique_code LIMIT 10
這里面的執(zhí)行順序?yàn)?/p>
- 1.
from - 2.
on - 3.
join - 4.
where - 5.
select - 6.
group by - 7.
limit
即
寫的順序:select … from… where… group by… having… order by… limit [offset,](rows)
執(zhí)行順序:from… where…group by… having… select … order by… limit
知道這個(gè),我們?cè)倏催@個(gè)sql
不走索引 有order_type_code條件
SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 and order_type_code=00901 group by a.unique_code LIMIT 10
和
走索引 沒有order_type_code條件
SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 group by a.unique_code LIMIT 10
和走索引有沒有order_type_code條件
SELECT * from t_item_detail a left join t_order_detail d on a.order_code=d.order_code and d.order_type_cod=‘00901' left join t_connection b on a.unique_code = b.funds_unique left join t_capital_detail c on b.capital_unique = c.unique_code where item_receipt_disbursement=1 and a.is_deleted=0 group by a.unique_code LIMIT 10
會(huì)發(fā)現(xiàn) 在不走索引有order_type_code條件的那個(gè)sql中, 在執(zhí)行到where的時(shí)候,需要去找到條件 order_type_code=00901 ,但是order_type_code這個(gè)字段沒有索引,所以數(shù)據(jù)庫(kù)就去對(duì)order_detail進(jìn)行全表掃描。
因此解決方案
就是給order_type_code加上索引,或者給 left join on就加上條件order_type_code=xxx ,直接過(guò)濾掉
因此,謹(jǐn)記,大表查詢的時(shí)候,where 的條件千萬(wàn)記得加上索引?。。?!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
將MySQL help contents的內(nèi)容有層次的輸出方法推薦
如何將MySQL help contents的內(nèi)容有層次的輸出呢?下面小編就為大家?guī)?lái)一篇將MySQL help contents的內(nèi)容有層次的輸出方法推薦。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,給大家一個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-03-03
如何解決mysqlimport: Error: 13, Can''t get stat of 的問(wèn)題
本篇文章是對(duì)解決mysqlimport: Error: 13, Can't get stat of問(wèn)題的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Lost connection to MySQL server during query的解決
經(jīng)常在執(zhí)行sql語(yǔ)句時(shí),會(huì)發(fā)現(xiàn)這個(gè)問(wèn)題,一般就是連接mysql數(shù)據(jù)庫(kù)不穩(wěn)定2008-06-06
mysql 批量更新與批量更新多條記錄的不同值實(shí)現(xiàn)方法
在mysql中批量更新我們可能使用update,replace into來(lái)操作,下面小編來(lái)給各位同學(xué)詳細(xì)介紹mysql 批量更新與性能吧2013-10-10
Windows10下mysql 8.0.19 winx64安裝教程及修改初始密碼
這篇文章主要為大家詳細(xì)介紹了Windows10下mysql 8.0.19 winx64安裝教程及修改初始密碼,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

