mysql索引

250 阅读5分钟

一、适合索引创建的情况

索引是帮助MysqL高效获取数据的数据结构,建立索引的目的是为了减少磁盘IO的次数。

  1. 字段的数值有唯一性的限制 索引本身可以起到约束的作用,比如唯一索引、主键索引均有唯一性索引的约束,因此在数据表中,如果某个字段是唯一的,便可以直接创建唯一性索引或主键索引。通过使用索引可以更快地确定某条记录。 例如,学生表中学号是具有唯一性的字段,为该字段建立唯一性索引可以很快确定某个学生的信息,但如果使用学生姓名(存在同名现象)会降低查询效率。

业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。唯一索引尽管影响了插入速度,但这个速度损耗可以忽略,可以明显提高查找速度。

  1. 频繁作为where查询条件的字段 当某个字段在select语句中的where条件中经常被使用,该字段需要建立索引。在大数据的情况下,创建普通索引可以大幅提升数据查询的效率。

  2. 经常group by和order by的字段 索引是让数据按照某种顺序(有序的)进行存储或检索,当使用group by对数据进行分组查询,或使用order by对数据进行排序的时候,这种有序的特性会提升查询的效率,因此需要对分组或者排序的字段进行索引。如果待排序的字段有很多,可以在这些字段上建立组合索引。

  3. update、delete的where条件字段 当对数据按照某个条件进行查询后在进行update或delete的操作,如果对where字段创建了索引,便可根据where条件检索出这条记录,然后再对它进行删除或更新,可以大幅提升效率。如果进行更新的时候,更新的字段是非索引字段,由于非索引字段更新不需要对索引进行维护,提升的效率会更明显。

  4. distinct字段需要创建索引 由于索引有序的特性,distinct字段建立索引后,去重的效率会大幅提升。

  5. 使用字段类型小的创建索引 类型大小代表数据范围的大小,比如TINYINT,MEDIUMINT、INT、BIGINT等,它们占用的存储空间依次递增,表示的整数范围依次递增。如果对某个整数字段建立索引,在表示的整数范围允许的情况下,让索引字段使用较小的类型,比如使用INT就不要使用BIGINT,能使用MEDIUMINT就不使用INT。有如下原因:

  • 数据类型越小,查询比较的操作越快
  • 数据类型越小,索引占用的存储空间越少,一个数据页可以存放更多的记录,减少磁盘io的次数,可以把更多的数据页缓存在内存中,从而加快读写效率。

对于表的主键更加适用,因为不仅聚簇索引会存储主键值,其他所有的二级索引(非聚簇索引)都会存储一份记录的主键值,如果主键值使用更小的数据类型,可以节省更多的存储空间和提高IO效率。

  1. 使用字符串前缀创建索引 当字符串很长时,存储一个字符串需要占用很大的存储空间,为该字符串创建索引时,会引起如下问题。
  • B+树索引中的记录需要把该列的完整字符串存储起来,费时,字符串越长,在索引中占用的存储空间越大。
  • B+树索引中索引列存储的字符串很长,字符串比较时会耗费更多时间。 可以通过截取字符前面的一部分建立索引(前缀索引)。查找记录虽然不能精确定位到记录的位置,但是能定位到相应前缀所在的位置,然后根据前缀相同记录的主键值回表查询完整的字符串值。节约空间和时间。但无法使用索引排序,只能使用文件排序。
  1. 散列性高的字段适合作为索引

联合索引把散列性高的字段放在左侧

  1. 使用最频繁的索引放在联合索引的左侧
  2. 多个字段创建索引时,联合索引优于单值索引

总结:实际工作中索引的数目并不是越多越好,单张表的索引数量不超过6个。①每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。②索引会影响INSERT、DELETE、UPDATE等语句的性能,表中的数据更改的同时,索引也会进行调整和更新,会造成负担。③优化器在选择优化查询时,会根据统一信息,对每一个可以用到的索引进行评估,以生成一个最好的执行计划。如果同时有很多个索引都可以用于查询,会增加MySQL优化器生成执行计划的时间,降低查询性能。

二、不适合索引创建的情况

  1. 在where、group by、order by条件中使用不到的字段,不创建索引
  2. 数据量小的表最好不创建索引
  3. 大量重复性数据(散列性低)的字段不创建索引
  4. 避免对经常更新的表创建过多索引
  • 频繁更新的字段不一定要创建索引,更新数据,需要索引,索引太多,更新索引会造成负担,影响效率。
  • 建立索引虽然提高了查询速度,同时降低更新表的速度。
  1. 无序的列不建立索引
  2. 删除不使用或很少使用的索引
  3. 不创建冗余或重复的索引