MySQL InnoDB 引擎中的 聚簇索引(Clustered Index) 和 非聚簇索引(Non-Clustered Index) 有以下几个主要区别:
1. 数据存储方式
- 聚簇索引(Clustered Index):数据的存储顺序和索引的顺序是相同的。也就是说,表中的数据按照聚簇索引的顺序物理存储在磁盘上。因此,聚簇索引直接决定了数据表的存储顺序。 在 InnoDB 中,主键索引就是聚簇索引。数据行本身存储在 B+ 树的叶子节点中。
- 非聚簇索引(Non-Clustered Index):非聚簇索引的存储顺序与数据的物理存储顺序无关。它是一个独立的索引结构,存储索引列的值以及与该值相关的数据行的指针(或者称为 ROWID)。非聚簇索引的叶子节点存储的是指向数据行的指针,而不是数据本身。
2. 索引和数据的关系
- 聚簇索引:数据表的主键索引默认就是聚簇索引。聚簇索引的叶子节点中存储了完整的数据记录,因此读取时会直接返回数据。
- 非聚簇索引:非聚簇索引并不包含数据行本身,而是包含数据行的指针。非聚簇索引需要通过索引值找到数据记录,然后再去表中查找对应的数据行。这种查找过程称为“回表”。
3. 存储结构
- 聚簇索引:聚簇索引的 B+ 树的叶子节点包含了实际的数据行。当你创建一个聚簇索引时,数据表会按照该索引进行排序。由于数据表中的数据按聚簇索引顺序排列,因此表中只能有一个聚簇索引。
- 非聚簇索引:非聚簇索引的 B+ 树叶子节点仅包含索引字段的值和对应数据行的指针。因此,同一表中可以有多个非聚簇索引。
4. 性能
- 聚簇索引:聚簇索引对于范围查询(如
BETWEEN
,>
,<
)非常高效,因为数据在磁盘上的顺序已经和索引顺序一致。通常聚簇索引对于数据的插入、删除和更新较为高效,因为这些操作不需要像非聚簇索引那样额外维护指针。 - 非聚簇索引:非聚簇索引查询效率相对较低,因为它们需要额外的回表操作,首先从索引中查找目标记录的指针,再去表中查找实际的数据。
5. 索引数量
- 聚簇索引:每个表只能有一个聚簇索引,因为数据本身只能按一种顺序进行存储。
- 非聚簇索引:每个表可以有多个非聚簇索引,这些索引可以根据不同的查询需求创建。
6. 使用场景
- 聚簇索引:适合那些查询时经常依赖范围扫描的场景(如日期、ID 范围等),并且通常用于主键索引。
- 非聚簇索引:适合经常进行特定列查询的场景,比如经常按某个字段查找的情况,或查询条件中经常使用非主键字段。
总结
- 聚簇索引:数据按照索引顺序存储在磁盘上,只有一个,通常是主键索引。
- 非聚簇索引:索引结构独立于数据存储,包含指向数据的指针,可以有多个。
对比
特性 | 聚簇索引 (Clustered Index) | 非聚簇索引 (Non-Clustered Index) |
数据存储顺序 | 数据存储顺序和索引顺序一致,数据按照索引顺序存储 | 数据存储顺序与索引无关,索引与数据表分开存储 |
数据存储位置 | 数据本身存储在索引的叶子节点中 | 数据不在索引中,索引存储的是指向数据行的指针 |
表中的索引数量 | 每个表只能有一个聚簇索引(通常是主键索引) | 每个表可以有多个非聚簇索引 |
查询效率 | 对范围查询非常高效,直接返回数据 | 查找索引后需要回表操作,查询效率相对较低 |
回表操作 | 无需回表操作,索引和数据在同一结构中 | 需要回表操作,从索引中查找指针,再访问实际数据行 |
维护成本 | 插入、删除和更新操作可能会导致数据重排,性能受影响 | 需要单独维护指针,删除或插入时可能需要更新索引结构 |
存储结构 | 索引的叶子节点存储实际数据 | 索引的叶子节点存储索引值和指向数据行的指针 |
适用场景 | 适用于主键查询、范围查询等,通常用于主键索引 | 适用于单列或多列的查询索引,通常用于快速查找非主键字段 |
创建方式 | 通过创建主键或唯一索引时自动创建(默认主键是聚簇索引) | 通过 CREATE INDEX 语句显式创建 |
评论留言
欢迎您,!您可以在这里畅言您的的观点与见解!
0 条评论