索引失效的若干种情况

0. 建表

      上图首先建了一个staffs表,然后插入了三条数据,最后建立在一个组合索引

2.索引优化

      我们把组合索引比作成一辆火车,第一个字段为火车头,其他的字段比作一节车厢,火车能运行的前提条件是火车头不能断掉,如果中间车厢断了,那么后续车厢也不能跑了.总之能够跑动的车厢所代表的索引都有效.也就是说组合索引只有一部分索引字段被使用.一部分失效.

2.1 全值匹配我最爱

      也就是查询条件全部用到了索引


 2.2 最佳左前缀法则

   上图的情况, 查询条件直接用到了火车头,索引有效,但也仅仅是用到了一个字段.

    上图的情况,查询条件用到了火车头和第二节车厢,索引有效,但也仅仅是用到了两个字段

   上图的情况,查询条件用到了 火车头和第三节车厢,由于第二节车厢断了,所以索引只用到了一个字段(火车头)

    上图的情况,火车头没了,索引全部失效.

2.3 不能在索引列上干任何操作(计算,函数,类型转换)

   由于对name进行了字符串截取,虽然可以查到数据,但是索引失效

2.4 存储引擎不能使用索引中范围条件右边的列

   结合上面的图分析值,索引用到一个,二个,三个的时候,key_len分别对应74 ,78, 140.

    此处用到了name和age字段,由于age是个范围查询,索引pos字段上的索引失效

2.5 尽量使用覆盖索引(只访问索引的查询),减少select *

     这张图与2.4节的图很相似,2.4中是select *,此处是select name,age,pos,此处用到了覆盖索引,索引type是ref,性能好于range,尽管只用到了一个字段.另外Extra中显示用到Using index 和Using where ,表明只需要从索引树中寻找数据,不需要到表中寻找,而2.4中仅仅只有Using where,表明需要到表中寻找.因此2.4中的查询性能低于次此处.

2.6 mysql在使用不等于(!=或者<>)的时候索引失效

     type为ALL,表明是全表扫描,索引失效

2.7 is null, is not null 也无法使用索引


2.8 like以通配符开头("%abc..."),索引会失效

 

   可以看到表里有一个name为axyd的数据


   很可惜  like  '%xy%'会导致索引失效,如何解决呢,用覆盖索引,也就是select字段全部都被建立了索引.

       这里select的字段全部都建立在索引上,所以解决了通配符在前头导致索引失效的问题.当然你如果仅仅select 索引字段中的一部分字段,也不会导致索引失效.总之只要select字段是索引字段的子集就没问题.

2.9 字符串不加单引号,索引会失效

   这种情况MySQL会将数字转换成string帮你查询,导致了索引失效,下面的图加了单引号,索引有效!

2.10 少用or,用它来连接时索引会失效


3. 总结


猜你喜欢

转载自blog.csdn.net/u012150590/article/details/79943541