首先我們還是先把表結(jié)構(gòu)說下:用戶表tb_user結(jié)構(gòu)如下:
成都創(chuàng)新互聯(lián)公司專注于辰溪網(wǎng)站建設服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供辰溪營銷型網(wǎng)站建設,辰溪網(wǎng)站制作、辰溪網(wǎng)頁設計、辰溪網(wǎng)站官網(wǎng)定制、微信小程序服務,打造辰溪網(wǎng)絡公司原創(chuàng)品牌,更為您提供辰溪網(wǎng)站排名全網(wǎng)營銷落地服務。
1、 不要在索引列上進行運算操作, 索引將失效。
手機號phone字段有唯一索引,當根據(jù)phone字段進行函數(shù)運算操作之后,索引失效:
2、 字符串類型字段使用時,不加引號,索引將失效。
如果字符串不加單引號,對于查詢結(jié)果,沒什么影響,但是數(shù) 據(jù)庫存在隱式類型轉(zhuǎn)換,索引將失效。
3、 如果僅僅是尾部模糊匹配,索引不會失效。如果是頭部模糊匹配,索引失效。
接下來,我們來看一下這三條SQL語句的執(zhí)行效果,查看一下其執(zhí)行計劃:
由于下面查詢語句中,都是根據(jù)profession(專業(yè))字段查詢,profession字段是一個普通的索引, 我們主要看一下,模糊查詢時,%加在關(guān)鍵字之前,和加在關(guān)鍵字之后的影響。
經(jīng)過上述的測試,我們發(fā)現(xiàn),在like模糊查詢中,在關(guān)鍵字后面加%,索引可以生效。而如果在關(guān)鍵字 前面加了%,索引將會失效。
4、 用or分割開的條件, 如果or前的條件中的列有索引,而后面的列中沒有索引,那么涉及的索引都不會 被用到。
由于age沒有索引,所以即使id有索引,索引也會失效。所以需要針對于age也要建立索引。
5、 數(shù)據(jù)分布影響:如果MySQL評估使用索引比全表更慢,則不使用索引。
索引并不是時時都會生效的,比如以下幾種情況,將導致索引失效:
1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)
注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
2.對于多列索引,不是使用的第一部分,則不會使用索引
3.like查詢是以%開頭
4.如果列類型是字符串,那一定要在條件中將數(shù)據(jù)使用引號引用起來,否則不使用索引
5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引
此外,查看索引的使用情況
show status like ‘Handler_read%';
大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數(shù)
handler_read_rnd_next:這個值越高,說明查詢低效。
------------------
1、WHERE字句的查詢條件里有不等于號(WHERE column!=...),MYSQL將無法使用索引
2、類似地,如果WHERE字句的查詢條件里使用了函數(shù)(如:WHERE DAY(column)=...),MYSQL將無法使用索引
3、在JOIN操作中(需要從多個數(shù)據(jù)表提取數(shù)據(jù)時),MYSQL只有在主鍵和外鍵的數(shù)據(jù)類型相同時才能使用索引,否則即使建立了
索引也不會使用
4、如果WHERE子句的查詢條件里使用了比較操作符LIKE和REGEXP,MYSQL只有在搜索模板的第一個字符不是通配符的情況下才能
使用索引。比如說,如果查詢條件是LIKE 'abc%',MYSQL將使用索引;如果條件是LIKE '%abc',MYSQL將不使用索引。
5、在ORDER BY操作中,MYSQL只有在排序條件不是一個查詢條件表達式的情況下才使用索引。盡管如此,在涉及多個數(shù)據(jù)表的查
詢里,即使有索引可用,那些索引在加快ORDER BY操作方面也沒什么作用。
6、如果某個數(shù)據(jù)列里包含著許多重復的值,就算為它建立了索引也不會有很好的效果。比如說,如果某個數(shù)據(jù)列里包含了凈是
些諸如“0/1”或“Y/N”等值,就沒有必要為它創(chuàng)建一個索引。
where條件==order by 條件==group by 條件 按順序遵守 最佳左前綴法則
假設創(chuàng)建了復合索引:a,b,c
不在索引列上做任何的操作(計算、函數(shù)、顯式或隱式的類型轉(zhuǎn)換),否則會導致索引失效而轉(zhuǎn)向全表掃描
1、字符不加單引號會導致索引失效
name字段為varchar類型
這條sql發(fā)生了隱式的類型轉(zhuǎn)換:數(shù)值==字符串。所以導致了全表掃描,索引失效
應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
mysql中的范圍條件有:in/not in、 like、 、BETWEEN AND ;
后面的索引失效
in會導致索引全部失效?。?!
BETWEEN AND 范圍條件不會導致索引失效?。?!
盡量讓索引列和查詢列一致;減少select * 的使用
1、查詢表結(jié)構(gòu)
2、查詢表的索引結(jié)構(gòu)
聯(lián)合索引:name,age,post;說明add_time字段沒有添加索引
3、查看select * 的執(zhí)行計劃
4、查看 select name,age,pos的執(zhí)行計劃
5、如果select只用一部分索引
like以通配符開頭(’%abc…’)mysql索引失效會變成全表掃描的操作。
解決:可以使用 覆蓋索引 來解決這個問題!
1、先查看表上的索引
id、name、age、pos 四個字段上都有索引; 注意:name是聯(lián)合索引中的第一個,帶頭大哥!
2、查看表結(jié)構(gòu)
有個add_time字段沒有用到索引
3、查看執(zhí)行計劃
使用UNION ALL
假設創(chuàng)建了聯(lián)合索引 x(a,b,c)
ps:like雖然也是范圍查詢但是區(qū)別于、,%用在最前面就只用到索引a了;%用在最后面可以用到a+b+c!
下面的sql幾乎違背了上面的所有原則,索引依然全部生效。因為select是索引覆蓋的,select里不包含沒有建立索引的字段。因此總是用到索引的??梢钥闯鰜硭饕采w在sql優(yōu)化中的作用性