通過阿里雲監控sql的發現,剛上線的sql有性能問題,然後就查這是什麼原因導致的
由於這個sql很長,關聯了很多表,直接explain解釋執行過程,發現有個表是全表掃描
通過sql我們發現,docId的索引是有的,爲什麼還是全表掃描呢?而且掃描的行數比單表的行數還多,這就很是不解,有索引爲啥索引走不了呢?
剛開始以爲是關聯驅動表的問題,因爲inner join 時,mysql會將有索引的表選爲被驅動表,由於原來用的left join,改成了inner join,發現還是沒有啥效果,並沒有什麼卵用
這就讓我百思不得其解,然後我就寫了如下sql,驗證索引是否生效
select * from doc_org_relation where node_id = 116119;
得到的explain解釋卻是這樣的
奇怪爲什麼還是全表掃描,node_id我也有索引的,爲什麼是全表掃描,這徹底毀了我sql的三觀啊,爲啥沒走索引呢?
後來看了一眼表設計,發現問題了,由於表設計node_id爲varchar類型,然後查詢的時候,在某種情況下會傳Integer類型過來,導致查詢的sql條件是int類型的,查詢類型和字段類型不匹配,導致添加的索引失效
於是將sql調整爲
explain select * from doc_org_relation where node_id = '116119';
然後再查看執行過程,發現走索引了,至此,問題解決
總結:
- 保證被驅動表的join字段已經被索引
- left join 時,選擇小表作爲驅動表,大表作爲被驅動表
- inner join 時,mysql會自己幫你把小結果集的表選爲驅動表
- 子查詢儘量不要放在被驅動表,有可能使用不到索引
- 能夠直接多表關聯的儘量直接關聯,不用子查詢
- 查詢條件時,如果表字段類型和查詢時條件不一致,儘管查詢數據沒問題,但是會導致查詢的條件索引失效