# 第三节 聚簇索引和非聚簇索引

# 1、查字典

# ①根据部首检字表

[煌]→[火字旁]→[煌 367]→[直接从正文中到 367 页找到这个字]

相当于我们在索引中存储了数据的物理地址。

这类似于『聚簇索引』的机制。

# ②根据拼音检字表

[煌]→[huang]→[首字母 H]→[黄 355]→[需要到检字表提供的页码范围内进一步查找]

相当于我们在索引中没有保存数据的物理地址,而只是保存了逻辑地址。

这类似于『非聚簇索引』的机制。

# 2、聚簇索引

# ①概念

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。聚簇索引就是按照每张表的主键构造一棵 B+ 树,同时叶子节点中存放的就是整张表的行记录数据——相当于把原始数据也保存到了索引中。也将聚簇索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分。

每张表只能拥有一个聚簇索引。

InnoDB 通过主键聚集数据。如果没有定义主键,innoDB 会选择非空的唯一索引代替。如果没有这样的索引,innoDB 会隐式的定义一个主键来作为聚簇索引。

# ②评价

# [1]优点

  • 数据访问更快,因为聚簇索引将索引和数据保存在同一个 B+ 树中,因此从聚簇索引中获取数据比非聚簇索引更快。
  • 聚簇索引对于主键的排序查找和范围查找速度非常快

# [2]缺点

  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键
  • 更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新
  • 二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据

# 3、非聚簇索引

聚簇索引之上创建的索引称之为非聚簇索引,非聚簇索引访问数据总是需要二次查找。非聚簇索引叶子节点存储的不再是行的物理位置,而是主键值。通过非聚簇索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的 Page Directory 找到数据行。

InnoDB 非聚簇索引的叶子节点并不包含行记录的全部数据,叶子节点除了包含键值外,还包含了相应行数据的聚簇索引键。

非聚簇索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个非聚簇索引。在 InnoDB 中有时也称非聚簇索引为二级索引或辅助索引。

# 4、小结

  • 数据库索引用于加速查询
  • 虽然哈希索引是 O(1),树索引是 O(log(n)),但 SQL 有很多“有序”需求,故数据库使用树型索引
  • InnoDB 不支持哈希索引
  • 数据预读的思路是:磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载更多的数据,以便未来减少磁盘 IO
  • 数据库的索引最常用 B+ 树:
    • 很适合磁盘存储,能够充分利用局部性原理,磁盘预读;
    • 很低的树高度,能够存储大量数据;
    • 索引本身占用的内存很小;
    • 能够很好的支持单点查询,范围查询,有序性查询;

上一节 回目录