關(guān)于MySQL索引的命中問題统舀,做了一點測試觅够。
首先态蒂,關(guān)于索引無法命中的問題堰汉,查了不少資料辽社,大概是這么說的:
- 在使用LIKE關(guān)鍵字進行查詢的查詢
? ? 如果匹配字符串的第一個字符為“%”,索引不起作用翘鸭。只有“%”不在第一個位置滴铅,索引才會生效。
- 使用OR關(guān)鍵字的查詢
? ? 查詢語句的查詢條件中只有OR關(guān)鍵字就乓,且OR前后的兩個條件中的列都是索引時汉匙,索引才會生效,否則生蚁,索引不生效噩翠。
- 使用聯(lián)合索引的查詢
? ? 只有查詢條件中使用了這些字段中第一個字段時,索引才會生效邦投。
我寫了兩百來萬數(shù)據(jù)伤锚,測試了一下。
首先是LIKE查詢志衣,id是主鍵屯援,t_password建了索引猛们,
? ? - 當(dāng)前面沒有"%",rows是1325119條(password_school是我建的t_password和t_school的聯(lián)合索引玄呛,后面會用到)阅懦;
- 前面有"%"時,rows是2690239,可是看到此時possible_keys是null,看起來確實是全表掃描了徘铝,但是key是有值的(password是我建的t_password的索引名字)耳胎;
可以看出,執(zhí)行時間慢了不少惕它。
那么假設(shè)是沒有索引的字段呢怕午?
可以看到,執(zhí)行時間比有索引的的模糊搜索慢了很多淹魄。
既然前面加"%"無法命中索引郁惜,為什么執(zhí)行速度卻還是比沒有索引的字段快這么多呢?
- 從EXPLAIN里面可以看到甲锡,當(dāng)前面不加"%"兆蕉,rows是1325119;而前面加了"%"時缤沦,rows是2690239虎韵,也就是表的總行數(shù),沒有索引的字段pic_url也是2690239缸废,但是這兩者速度差了好幾倍包蓝。
我的想法:LIKE查詢有索引的字段,關(guān)鍵字前面沒有"%"時企量,是可以準確命中索引测萎,直接查符合條件的行;而關(guān)鍵字前面有"%"時届巩,無法命中索引硅瞧,但是執(zhí)行時也是全索引搜索,而不是全表搜索姆泻,執(zhí)行速度比不加索引還是快了很多的零酪。
關(guān)于聯(lián)合索引其實也是一樣的,如果只給出了第一個條件拇勃,是能準確命中索引的四苇;而如果沒有給出第一個條件,只給出第二個方咆,無法準確命中索引月腋,但是也是全索引掃描,速度其實也比較快(當(dāng)然不如準確命中索引,數(shù)據(jù)量越大就越明顯)榆骚,圖就不上了片拍,有興趣的可以自己試一試。
我的結(jié)論:廣為流傳的幾個索引失效的問題妓肢,其實并不是索引失效捌省,只是索引不能準確命中,速度會相對慢一點碉钠,但也遠快于沒有索引的字段纲缓。
剛了解索引的時候就在想,MySQL怎么這么笨呢喊废,動不動就不能命中索引祝高。其實并沒有那么笨。
ps:聯(lián)合索引的測試懶得貼了污筷,有興趣就自己試試唄工闺。