Mysql:适合和不适合创建索引的情况

适合创建索引的情况

情况1:字典值在业务上是唯一的

比如说用户表的身份证字段,此字段在业务上肯定是唯一性的,因此我们可以给此字段添加唯一索引

情况2:where条件中频繁使用的字段(包含update和delete)

where条件中频繁使用的字段。这个应该很好理解,其实很多表会有code字段,常常通过:
select * from A where code = 1;像code在where中就是一个频繁使用的字段,可以添加普通索引

情况3:经常group by 和 order by 的字段

经常group by 和 order by 的字段适合添加索引,group by具体看业务需要,而order by常见的有create_time等时间类型的字段。
如果是单个字段,一般加普通索引即可,若分组或排序是多个字段,需要使用组合索引

情况4:distinct字段需要加索引

distinct配合的字段可以加普通索引,但如果distinct匹配的字段多,就没必要在每个字段加索引了

情况5:多表连接

  1. 在where字段添加普通索引
  2. join的字段也可添加普通索引。如 A INNER JOIN B ON A.code = B.code,可在B或A的code字段可添加索引
  3. 如 A INNER(LEFT) JOIN B ON A.code = B.code。A和B表的code都可以添加索引且都能同时触发
  4. 如果A和B中的code只有其中1个存在索引,尽量让有索引的表作为被关联表
  5. 对于内连接且A和B中的code都加了索引条件下,选择小表作为关联表,大表作为被关联表。

情况6:文本类型字段索引时,指定索引长度

通常某个文本字段中可能会保存很长的字符串,所以在指定类型长度时,会设得比较长。如果为此字段创建索引,在一定程度上会使索引效率没有特别高效

有个推荐做法是:为文本类型创建索引时,只索引一定长度即可,比索引全长度要高效地多。

那具体索引多长比较好呢?有个区分度的公式:

SELECT count(DISTINCT left(列名,索引长度)) / count(*) from 表名

索引长度可以自己一个个试下,从10 -> 15 -> 20 -25...都可试下,区分度越接近1是最好的,一般建议区分度在90%以上,但如果真的相差无几,选索引长度最小的那个

其实加前缀索引,有两个缺点:

  1. 就是查出来的数据不一定完全准确,因为只索引字符串一定前缀(相当只比较前缀部分),后面字符串部分可能是不一样的
  2. 不支持order by,或者说使用order by 后排序不准确了

情况7:区分度高的列创建索引

如何定义区分度高?还是刚才公式:

SELECT count(DISTINCT left(列名,索引长度)) / count(*) from 表名

越接近1区分度越高,一般有33%以上创建的索引都是比较高效的

PS;如果创建联合索引,把区分度最高的字段放在第1位

情况8:创建联合索引时,最频繁使用的字段放在第1位

创建联合索引时,最频繁使用的字段放在第1位

情况9:多个字段都需要创建索引时,联合索引优于单值索引

多个字段都需要创建索引时,联合索引优于单值索引。比如说where中有好几个字段都需要创建索引,要么一个个给其创建索引,要么创建联合索引。在这种情况下,联合索引是更加合适的

总结

一张表的索引并不是越多越好,一般不建议不超过6个。索引多了也有影响:

  1. 索引占据空间越大(这个可以忽略)
  2. 在增删改时,效率会越低下(这个才是索引多了,我们最担心的点)

不适合创建索引的情况

情况1:where条件中用不到的字段

这个很简单理解,很多字段会select,但不会作为where条件,就没必要创建索引

情况2:数据量小的表,不需要创建索引

数据量小的表,不需要创建索引

情况3:大量重复数据的列不需要创建索引

比如说性别字段,就男和女,又或者是枚举字段,保存的都是一些数字枚举...这些都没必要创建索引

情况4:避免对经常更新的表创建较多索引

image

情况5:不建议用无序的值作为索引

image
这是看视频给到的建议,但大家可以忽视。大部分情况系列都是无序的,由于数据量大查询缓慢,即使无序我们也得加索引

posted @ 2022-11-29 17:16  爱编程DE文兄  阅读(608)  评论(0编辑  收藏  举报