一、索引哪些情况会失效
1.InnoDB引擎里面又俩种索引类型(主键索引、普通索引)
InnoDB用了B+树的结构来存储引擎数据
当我们使用索引进行数据查询的时候,最终会到主键索引树种查询对应的数据进行返回
理论上来说,使用索引列查询,就能很好的提升查询效率,但是不规范的使用会导致索引失效,从而无法发挥索引本身的价值。
导致索引失效的情况又很多:
1.在索引列上做运算:比如使用函数,Mysql在生成执行计划的时候,它是根据统计信息来判断是否使用索引的。而在索引列上加上函数的运算导致MySql无法识别索引列也就不会再走索引了。
但是!!!!
MySql8开始,增加了函数索引可以解决这个问题!!!
2.在一个由多列构成的组合索引中,需要按照最左匹配法则:也就是从索引的最做列开始顺序检索,否则不会走索引。在组合索引中,索引的存储结构是按照索引列的顺序来存储的,因此在sql中也需要按照啊这个顺序才能进行逐一匹配。否则InnoDB无法识别索引就回导致索引失效
3.当索引列存在隐式转换的时候,比如索引列是字符串类型,但是在sql查询中没有使用引号,那么MySql会自动进行类型转化,从而导致索引失效在索引列使用不等于号、not查询的时候,由于索引数据的检索效率非常低,因此Mysql引擎会判断不走索引。
4.通使用like通配符匹配后缀%xxx的时候,由于这种方式不符合索引的最左匹配原则,所以也不会走索引。但是反过来,如果通配符匹配的是前缀xxx%,符合最左匹配,也会走索引。
5.使用or连接查询的时候,or语句前后没有同时使用索引,那么索引会失效。只有or左右查询的字段都是索引列的时候才会生效
二、索引不适合哪些场景
1.数据量少的不适合添加索引:通过比较,在数据量小于32W时,加索引和不加索引查询速度差别不大,数据大于50W后,随着数据量的增大,加索引的查询速度相对会越来越慢。100W级别数据后,加索引表的查询速度急速下降。表记录太少,是否创建索引对查询效率的影响并不大。甚至说,查询数据花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化的效果。
2.更新比较频繁的也不适合加索引:因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候会造成负担,从而影响效率。
3.区分度低的字段不适合加索引:加索引是为了快速定位数据,如果重复率高不但加索引不会提高查询的速度反而严重降低了更新数据的速度,比如性别基本上只有男和女重复率高;
三、索引的一些潜规则
1.覆盖索引:覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖
2.回表:如果索引的列在 select 所需获得的列中(因为在 mysql 中索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。
3.数据结构:B+树
4.最左前缀原则:在组合索引中,索引的存储结构是按照索引列的顺序来存储的,因此在sql中也需要按照啊这个顺序(从左到右)才能进行逐一匹配。否则InnoDB无法识别索引就回导致索引失效
5.索引下推:是从 MySQL5.6 开始引入一个特性,英文是 index condition pushdown ,一般简称为 ICP ,索引下推通过减少回表的次数,来提高数据库的查询效率