mysql 索引失效的情況


索引失效的幾種情況

  1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)

  要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

  2.對於多列索引,不是使用的第一部分,則不會使用索引(靠左原則)

  3.like查詢以%開頭的列索引會失效

  4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來,否則不使用索引

  5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引

   6 不等於(!= ,<> ),EXISTS,not in,is  not null,>,<都會失效,in(in里面包含了子查詢)(非主鍵索引)

下面對這幾種情況進行測試

例如有個表 test 有 id,name,age三個字段

首先插入10000條

INSERT INTO test(id,name,age)

VALUES

('5','5test','5'),('6','6test','6'),('7','7test','7'),......('9999','9999test','9999');

上面是一種批量插入的方法,可以減少數據連接的次數,有興趣的可以試試,這個我沒在代碼(xml)里面試過

數據已經有了

使用id作為索引

ALTER TABLE testADD index_id(id);

EXPLAIN select * from test where id= '26'

可以看得出來是走了索引的;如果表中數據量不夠大,msyql覺得全盤掃描的時間比走索引的時間短的話可能就不會走索引了

組合索引(靠左原則)

現在增加組合索引

ALTER TABLE testADD name_age (name,age);

1 根據name精確查詢時

EXPLAIN select * from test where name = '26test'

可見是走了 name_age索引的: 靠左原則

2 根據name+age查詢時(靠左原則)

EXPLAIN select * from test where name = '26test' and age='26'

EXPLAIN select * from test where age =26 and name = '26test'

3 使用age查詢時(索引失效的第二種情況)

EXPLAIN select * from test where age='26'

沒有走name_age索引: 原因是mysql的靠左原則(根據where最最側的匹配是否有索引),所以不使用name_age索引

問題來了:如果這樣的話會使用哪個索引呢?

EXPLAIN select * from test where name='26' and id='26'

可見possible_keys有兩個索引,但是最后使用的還是 id_index索引,因為它耗時最少

4 組合索引使用 like 時

EXPLAIN select * from test where age like '%26%' and name = '26test'

使用的還是name_age索引,為什么呢? 因為雖然like不會走索引 但是 name 遵循了靠左原則所以還是會使用索引

使用這條時:EXPLAIN select * from test where name like '%26%' and age='26'

或 EXPLAIN select * from test where id like '%26%'
(索引失效的第三種)

結果就是沒有使用索引,因為name使用的是模糊查詢

5 組合索引(失效)+非組合索引

EXPLAIN select * from test where name like '%26%' and age='26' and id='26'

可見使用的是 id_index

6 非組合索引使用like查詢(索引失效的第三種)

EXPLAIN select * from test where id like '%26%'

7 or 條件如果都有所有就會使用索引

一下兩種都會走索引

EXPLAIN select * from test where id ='26' or name='26test';

EXPLAIN select * from test where id ='26' or age='26' and name='26test';

因為id和name(name_index:靠左原則)都有索引所以最后還是走了索引----index_merge 索引合並

8 or條件中 其中之一沒有索引就會使索引失效(索引失效的第一種)

EXPLAIN select * from test where id ='26' or age='26';

id有索引但是age不是索引,所以就走了全盤掃描

9 字符串沒有加引號(索引失效的第四種)

EXPLAIN select * from test where name=26


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM