2020-08-12

案例所用的表结构、索引、与数据如下:

这里写图片描述
这里写图片描述

索引失效与优化

这里写图片描述

1、全值匹配我最爱

这里写图片描述

2、最佳左前缀法则(带头索引不能死,中间索引不能断)

如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且 不跳过索引中的列。
正确的示例参考上图。

错误的示例:
带头索引死:
这里写图片描述
中间索引断(带头索引生效,其他索引失效):
这里写图片描述

3、不要在索引上做任何操作(计算、函数、自动/手动类型转换),不然会导致索引失效而转向全表扫描

这里写图片描述

4、mysql存储引擎不能继续使用索引中范围条件(bettween、<、>、in等)右边的列

这里写图片描述

5、尽量使用覆盖索引(只查询索引的列(索引列和查询列一致)),减少select *

这里写图片描述

6、索引字段上使用(!= 或者 < >)判断时,会导致索引失效而转向全表扫描

这里写图片描述

7、索引字段上使用 is null / is not null 判断时,会导致索引失效而转向全表扫描

这里写图片描述

8、索引字段使用like以通配符开头(‘%字符串’)时,会导致索引失效而转向全表扫描

这里写图片描述
由结果可知,like以通配符结束相当于范围查找,索引不会失效。与范围条件(bettween、<、>、in等)不同的是:不会导致右边的索引失效。

问题:解决like ‘%字符串%’时,索引失效问题的方法?
使用覆盖索引可以解决。
这里写图片描述
这里写图片描述

9、索引字段是字符串,但查询时不加单引号,会导致索引失效而转向全表扫描

这里写图片描述

10、索引字段使用 or 时,会导致索引失效而转向全表扫描

这里写图片描述

小总结

这里写图片描述

这里写图片描述

 

##########################################################################################

 

mysql 索引失效原因

一、单表查询时索引失效

     1、mysql查询单表时,查询得到的结果集占数据总量很大比例,mysql会认为全表扫描会优于索引,则不走索引。

       例:比如企业人员信息表 (userInfo),字段(user_id、user_name、user_type(vachar)),假设企业里有10w人,一千个管理层user_type为1,9万9千人为普通员工user_type为2,

      sql:select * from userInfo where user_type='2' 这时user_type字段索引可能会失效

      2、查询时where条件后的字段类型要与表结构中该字段类型一致,

      例:select * from userInfo where user_type=2 ,user_type在表结构中时字符类型,查询时没用有单引号包含起来则不走索引。

      3、在where条件后对索引字段加了函数转换或者运算逻辑(+、-、*、/、!、<>、%、like'%_'(%放在前面)、or、in (疑问、可能存在成本问题)、exist等)的处理,比如对时间戳字段进行日期格式化函数都会引起索引失效。

二、多表关联查询时索引失效

      1、在表结构设计阶段主表与关联表之间的关联字段的数据类型、数据长度、字段的编码格式以及字段的排序规则需要保持一致

三、组合索引

      1、当一张表的查询方式比较固定,这时候可以尝试创建聚集索引,查询时应当遵从组合索引的规则,最左原则,查询时使用最频繁的一列放在最左边,

      例:index(user_id,user_name,user_type)这是一个组合索引,当查询时如果想走索引则 

      sql:select * from userInfo where user_id='001' and user_name='小张' and user_type='1';这个时候是走了索引的,但是

               select * from userInfo where  user_name='小张' and user_type='1';这时user_id没有在where条件内将不走索引;

此例,user_id字段必须出现在where后面,不然索引将不会生效。

你可能感兴趣的:(MYSQL)