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

posted @ 2020-03-20 23:48  段佳伟  阅读(797)  评论(0编辑  收藏  举报