1.被索引字段發(fā)生隱式轉(zhuǎn)換
Mysql執(zhí)行器在執(zhí)行sql查詢的時候,會自動將與原字段類型不匹配的值進(jìn)行類型轉(zhuǎn)換
我們創(chuàng)建如下表

分別進(jìn)行如下sql查詢
explain select* from t_user where f_phone=139

可以看到,key是null,也就是說索引是沒有生效的,再換一種方式查詢
explain select * from t_user where f_phone="139"

此時,key為idx_phone也就是索引命中了。通過這個例子可以分析出,當(dāng)被索引字段與原字段類型不匹配的時候,索引就會失效
2.被索引字段使用了表達(dá)式計算
還是使用t_user表,我們執(zhí)行如下sql
explain select * from t_user where f_age-2=18;

索引是沒有被命中的,包括嵌套查詢,索引頁無法生效,比如如下sql
explain select * from t_user where f_age=(select f_age from t_user where f_phone='10086');

可以看到,子查詢2索引是生效的,同樣age字段也是索引字段缺沒有辦法生效
3.被索引字段使用了函數(shù)
explain select * from t_user where left(f_age,1)='10086';

小結(jié):為什么這三種情況會導(dǎo)致索引失效呢?
因為索引字段是依賴于整個BTree索引樹的遍歷,而索引樹遍歷又依賴于索引樹底層的葉子節(jié)點的有序性,當(dāng)被索引字段進(jìn)行了隱式轉(zhuǎn)換,表達(dá)式計算,函數(shù)計算后,這個字段新的排列順序和原來在索引樹的葉子節(jié)點層的排列順序不一樣,破壞了葉子節(jié)點的有序性,mysql執(zhí)行器無法判斷原來的索引是否還能被檢索,最后導(dǎo)致執(zhí)行器不使用索引
4.在like關(guān)鍵字后使用了左模糊查詢或者左右模糊查詢
explain select * from t_user where f_phone like '%10086';
explain select * from t_user where f_phone like '%10086%';

這兩條查詢語句索引都會失效,而使用右模糊查詢,索引就會生效
explain select * from t_user where f_phone like '10086%';

5.被使用的索引字段不是聯(lián)合索引的最左字段
我們先創(chuàng)建name和phone字段的聯(lián)合索引

我們只對name做條件查詢,如下
explain select * from t_user where f_name='小明';

可以看出索引是不生效的,如果查詢條件包含聯(lián)合索引最左字段,則索引依然會生效

小結(jié):4、5情況,為什么索引會失效呢?
因為mysql索引樹檢索遵循最左匹配原則,因為葉 子節(jié)點有序性也是建立在最左匹配原則之上
最后,思考下,如下sql的索引會生效嗎?原因又是什么呢?
explain select f_name,f_phone from t_user where f_name='小明';
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
答案是索引覆蓋