索引类型一般分为聚簇索引和非聚簇索引(联合索引、唯一索引、前缀索引等),这篇文章主要说的是聚簇索引。
聚簇索引是一种数据库索引类型结构,它实质上是一颗B+Tree,按照聚簇索引的键值进行顺序排序。
聚簇索引和非聚簇索引的区别
聚簇索引:
- 使用的B+Tree创建索引,叶子节点直接保存的对应每一行的数据,由于数据和索引是在一起的,并且数据一旦储存,顺序只有一种,所以一个表只能有一个聚簇索引。
- 聚簇索引是在存储引擎的基础上有的概念,所以不是所有的存储引擎都会有聚簇索引的,下面我们都是以InnoDB为例。
- 当InnoDB创建主键时,会默认帮主键创建聚簇索引,又称主键索引。如果没有创建主键时,会优先选择表中第一个NOT NULL的唯一索引当作聚簇索引,如果以上均没有InnoDB存储引擎会默认增加一个隐藏的字节数为6的字段ROW-ID作为聚簇索引。
在InnoDB中,聚簇索引的实例图:
InnoDB的聚簇索引
在InnoDB的聚簇索引中,叶子节点保存了索引键值和行数据,他们是以索引的键值顺序排列成一个链表,这样也非常适用于范围查找。
ps:MyISAM没有聚簇索引。
非聚簇索引:
- 使用的B+Tree树创建索引。
- 非聚簇索引也称为二级索引,MyISAM表没有聚簇索引,只有二级索引,在MyISAM中,单个或多个二级索引的叶子节点存放的都是数据行的引用地址。InnoDB表中,二级索引的叶子节点存放的是索引值和聚簇索引的ID值。
在MyISAM中,非聚簇索引的实例图:
MyISAM非聚簇索引
在MyISAM中,所有的非聚簇索引叶子节点中存放的都是数据引用的地址,所以索引占用空间相对比较小,所以搜索速度比较快。
在InnoDB中,非聚簇索引的实例图:
InnoDB非聚簇索引
在InnoDB中,非聚簇索引的叶子节点保存的是索引值和聚簇索引的值,当查询到聚簇索引值时,再需要从聚簇索引中查找的对应的行,需要进行二次查找,如果聚簇索引的值设置的比较大,那么索引占用的空间就比较大,这也是为什么MyISAM普遍要比InnoDB查询速度快的原因。
聚簇索引的优点:
- 提高查询性能:聚簇索引将行数据保存在叶子节点中,当直接用聚簇索引单行查询时,可以通过较少的I/O操作快速定位到所需的数据行并返回。
- 聚合查询:聚簇索引中的数据行是按照索引键值顺序排序,所以可以快速排序(SORT BY)、分组(GROUP BY)、汇总等。
- 范围查找:聚簇索引中的数据行是按照索引键值顺序排序,所以可以根据指定的返回快速查找所需的数据行并返回。
- 索引覆盖:由于聚簇索引中叶子节点保存了数据行的全部数据,因此在一些情况下。可以通过聚簇索引来覆盖查询的所有列,避免了查询需要回表的额外I/O操作,提高查询消息。(覆盖索引会单独出一篇)
- 减少存储空间:聚簇索引将行数据保存在叶子节点中,所以可以不用像非聚簇索引一样,单独维护一份索引数据。
使用聚簇索引注意的点:
- 一般InnoDB表都会建立主键,并设置自动增长,避免设置主键的时候使用无序ID进行插入操作,因为这样会导致一直在进行页分裂和页合并的操作(后面会写一篇文章细说页分裂和页合并)。
- 不要设置过长的值作为聚簇索引的值,因为辅助索引的叶子节点上存放了聚簇索引的值,会使得每一份辅助索引都特别的大,占用更多的物理空间。