详解 MySQL InnoDB 引擎中的聚簇索引和非聚簇索的区别

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 语句显式创建

你可能感兴趣的:(数据库,面试,mysql,数据库)