背景:有一天同事突然問我為什么加了in查詢就突然變慢了、小羊脫口而出:“in不走索引!” 於是就炸開了鍋:in不走索引!怎么可能? 但是在小羊同學腦子里、in不走索引為什么早就根深固體了?原因暫且不說,我們來探索真像。
環境:Windows10、MySQL5.7、可視化工具navicat。
場景1:當IN中的取值只有一個主鍵時
我們只需要注意一個最重要的type 的信息很明顯的提現是否用到索引:
type:連接類型(建議記到小本本上)
-
system:表只有一行記錄,相當於系統表
-
const:通過索引一次就找到,只匹配一行數據
-
eq_ref: 唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配
-
ref:非唯一性索引掃描,返回匹配某個單獨值的所有行用於=、<、> 操作符帶索引的列
-
range:只檢索給定范圍的行,使用一個索引來選擇行一般使用 between、<、>
-
index:只遍歷索引樹
-
ALL:全表掃描,性能最差
場景2:擴大IN中的取值范圍
此時仍然走了索引,但是效率明顯降低了
場景3:繼續擴大IN的取值范圍
發現此時已經沒有走索引了,而是全表掃描
結論:
當數據量很大的時候,in("大量數據"),in 查詢走索引也許不是最好的
但是!
當查詢的列是char類型,必須加""號才可走索引,否則導致全表掃描,會隨着表的增大而變得更慢
結論:
-
當in()種的數據很大時,不走索引
-
當查詢的列是char類型沒有加引號,mysql優化器會自動給填充引號,同時也會導致索引失效
-
當in()中存在子查詢、格式化函數等同樣也會使索引失效!
-