目录
一、聚簇索引(Clustered Index)
二、非聚簇索引(Non-Clustered Index)
三、示例说明
一、聚簇索引(Clustered Index)
定义:
聚簇索引是一种将数据存储和索引合为一体的索引方式。
-
表中的数据行按照索引的顺序存储。
-
索引的叶子节点直接存储完整的表数据。
特点:
-
数据与索引的紧密结合:表的数据行与聚簇索引的叶子节点绑定。
-
每张表只能有一个聚簇索引:因为数据的存储顺序只能按照一个索引排列。
-
索引的主键决定数据存储顺序:若表中定义了主键,则主键默认作为聚簇索引;否则,数据库会选择一个唯一键或者生成一个隐式键作为聚簇索引。
-
其他索引仅存储索引字段和主键,查询其他字段需要回表查询。
存储方式:
-
索引结构:基于 B+ 树。
-
叶子节点:直接存储完整的表数据。
-
非叶子节点:存储键值和指向子节点的指针。
优点:
-
查询性能高:按主键范围查询效率极高,因为数据是按主键顺序存储的。
-
数据访问更快:不需要通过额外的指针从索引找到数据。
-
减少 I/O 操作:索引和数据存储在一起。
缺点:
-
插入、更新性能受影响:如果插入的数据不符合当前排序规则,可能会引起数据页的分裂或移动。
-
索引占用存储空间较大:数据和索引共存导致节点大小较大,影响缓存效果。
-
二级索引存储复杂:非聚簇索引中的记录需要额外存储主键值来定位数据。
适用场景:
-
主键查询或范围查询频繁的场景。
-
数据插入和更新相对较少的场景。
二、非聚簇索引(Non-Clustered Index)
定义:
非聚簇索引是一种索引与数据分离的索引方式。
-
索引存储的是数据的位置,而不是数据本身。
-
数据行的存储顺序与索引无关。
特点:
-
索引独立于数据:索引的叶子节点存储数据的指针(或主键值)。
-
一张表可以有多个非聚簇索引:允许在不同列上建立多个索引。
-
支持灵活查询:可以为经常被查询的列创建非聚簇索引。
存储方式:
-
索引结构:基于 B+ 树。
-
叶子节点:存储键值和指向表数据的指针或主键值。
-
非叶子节点:存储键值和指向子节点的指针。
优点:
-
支持多个索引:灵活优化查询性能。
-
占用存储空间小:索引结构更紧凑。
-
插入、更新效率高:不会影响数据存储顺序。
缺点:
-
查询性能稍低:需要通过索引找到指针(或主键值),再访问数据,称为“回表”。
-
二次 I/O 操作:范围查询时需要大量回表操作,性能可能受影响。
适用场景:
-
复杂查询场景,例如多列查询或非主键查询。
-
数据更新和插入频繁的场景。
三、示例说明
假设有一个学生表 students,包含以下列:
• id(主键)
• name
• age
• score
聚簇索引示例
若 id 是主键,表将以 id 列构建聚簇索引,数据按 id 的顺序存储。例如:
聚簇索引(B+ 树叶子节点)
(id: 1, name: Alice, age: 20, score: 90)
(id: 2, name: Bob, age: 21, score: 85)
(id: 3, name: Charlie, age: 22, score: 95)
非聚簇索引示例
为 name 列创建非聚簇索引,索引存储 name 和主键 id,表数据与索引分离。例如:
非聚簇索引(B+ 树叶子节点) 数据表
(name: Alice, id: 1) (id: 1, name: Alice, age: 20, score: 90)
(name: Bob, id: 2) (id: 2, name: Bob, age: 21, score: 85)
(name: Charlie, id: 3) (id: 3, name: Charlie, age: 22, score: 95)
查询 name='Bob' 时,非聚簇索引会找到 id=2,然后回表查找数据。
四、总结
索引类型 | 优点 | 缺点 | 适用场景 |
聚簇索引 | 查询速度快,范围查询高效;数据按索引顺序存储。 | 插入/更新效率较低;每张表只能有一个聚簇索引。 | 读多写少,主键或范围查询频繁的场景。 |
非聚簇索引 | 支持多个索引;更新操作对数据影响较小。 | 查询需要回表,性能较聚簇索引略低。 | 复杂查询、非主键查询或写操作较多的场景。 |