跳到主要内容

簇聚索引与非簇聚索引

1. 什么是簇聚索引与非簇聚索引

除了按照实现方式来区分外,索引还可以分为「簇聚索引(Clustered Index)」与「非簇聚索引(Non-Clustered Index)」。

不论是簇聚索引还是非簇聚索引,都是使用 B+ 树 来实现的。而二者的核心区别只有一点:

簇聚索引:叶子节点存储了实际的数据 非簇聚索引:叶子节点存储了索引的键值

2. 为什么要区分簇聚索引与非簇聚索引

在实际开发中,我们通常都会为了提高查询效率,而使用索引。默认情况下,数据库会为 主键 会自动创建一个索引,这个索引是一个 簇聚索引

除了主键索引之外,为了加速不同场景的查询效率,我们还会其他常用的列创建索引,这些额外的索引都是 非簇聚索引

一个很简单的关于存储空间的取舍,如果所有的索引都保存了实际的数据,那么没有一个索引,都相当于把数据表复制了一份,这对于存储空间来说是一个很大的浪费。

一个合理的选择是,对于额外创建的索引,只保存主键的值。在这些索引中查询到主键后,再通过主键在主键索引中查询到实际的数据。

由于簇聚索引的叶子节点存储了实际的数据,所以对于一些数据库来说,簇聚索引是数据库实际的存储结构

3. 簇聚索引对查询的影响

3.1. 主键查询

由于簇聚索引的叶子节点存储了实际的数据,所以当使用主键查询时,可以查询索引就可以返回完整的数据了。

3.2. 非主键查询

使用非主键时,我们可以分为三种情况,分别是:

1. 覆盖索引

如果需要查询的列全部包含在索引中,那么数据库会直接使用索引中存储的数据,不会再去查询原始的数据表。

2. 非覆盖索引 - 回表

如果需要查询的列没有全部包含在索引中,那么查询会分为两步:

  1. 查询主键:数据库会先使用索引中包含的列进行查询,在非簇聚索引中,找到对应记录的主键
  2. 回表查询:通过主键,在主键索引中查询实际的数据,也就是回到簇聚索引中查询实际的数据

3. 无索引

如果查询的列没有索引,那么数据库会进行全表扫描,查询到所有的数据后,再进行过滤。