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:多表连接
- 在where字段添加普通索引
- join的字段也可添加普通索引。如 A INNER JOIN B ON A.code = B.code,可在B或A的code字段可添加索引
- 如 A INNER(LEFT) JOIN B ON A.code = B.code。A和B表的code都可以添加索引且都能同时触发
- 如果A和B中的code只有其中1个存在索引,尽量让有索引的表作为被关联表
- 对于内连接且A和B中的code都加了索引条件下,选择小表作为关联表,大表作为被关联表。
情况6:文本类型字段索引时,指定索引长度
通常某个文本字段中可能会保存很长的字符串,所以在指定类型长度时,会设得比较长。如果为此字段创建索引,在一定程度上会使索引效率没有特别高效
有个推荐做法是:为文本类型创建索引时,只索引一定长度即可,比索引全长度要高效地多。
那具体索引多长比较好呢?有个区分度的公式:
SELECT count(DISTINCT left(列名,索引长度)) / count(*) from 表名
索引长度可以自己一个个试下,从10 -> 15 -> 20 -25...都可试下,区分度越接近1是最好的,一般建议区分度在90%以上,但如果真的相差无几,选索引长度最小的那个
其实加前缀索引,有两个缺点:
- 就是查出来的数据不一定完全准确,因为只索引字符串一定前缀(相当只比较前缀部分),后面字符串部分可能是不一样的
- 不支持order by,或者说使用order by 后排序不准确了
情况7:区分度高的列创建索引
如何定义区分度高?还是刚才公式:
SELECT count(DISTINCT left(列名,索引长度)) / count(*) from 表名
越接近1区分度越高,一般有33%以上创建的索引都是比较高效的
PS;如果创建联合索引,把区分度最高的字段放在第1位
情况8:创建联合索引时,最频繁使用的字段放在第1位
创建联合索引时,最频繁使用的字段放在第1位
情况9:多个字段都需要创建索引时,联合索引优于单值索引
多个字段都需要创建索引时,联合索引优于单值索引。比如说where中有好几个字段都需要创建索引,要么一个个给其创建索引,要么创建联合索引。在这种情况下,联合索引是更加合适的
总结
一张表的索引并不是越多越好,一般不建议不超过6个。索引多了也有影响:
- 索引占据空间越大(这个可以忽略)
- 在增删改时,效率会越低下(这个才是索引多了,我们最担心的点)
不适合创建索引的情况
情况1:where条件中用不到的字段
这个很简单理解,很多字段会select,但不会作为where条件,就没必要创建索引
情况2:数据量小的表,不需要创建索引
数据量小的表,不需要创建索引
情况3:大量重复数据的列不需要创建索引
比如说性别字段,就男和女,又或者是枚举字段,保存的都是一些数字枚举...这些都没必要创建索引
情况4:避免对经常更新的表创建较多索引
情况5:不建议用无序的值作为索引
这是看视频给到的建议,但大家可以忽视。大部分情况系列都是无序的,由于数据量大查询缓慢,即使无序我们也得加索引