18. 什么是聚簇索引(第5题)
Clustered Index 数据和索引放在一起组成一个 B+ 树(数据在叶子节点,而非指针)。
用做主键索引。
19. 一个表中可以有多个(非)聚簇索引吗
聚簇 1 个, 非聚簇 Secondary Index 多个。
20. 聚簇索引 vs 非聚簇索引(特点)
| 特性 | 聚簇索引 Clustered | 非聚簇索引(Non-clustered) |
|---|---|---|
| 存储位置 | 叶子节点存储整行数据 | 叶子节点存储主键指针或rowid |
| 数据存储顺序 | 与索引顺序一一致 | 与数据存储顺序无关 |
| 每表数量限制 | 仅一个 | 可以多个 |
| 查询效率(主键) | 非常高(不需要回表) | 较低(需回表) |
| 查询效率(非主键) | 需先查询索引再回表 | 与字段相关,可能需要多次回表 |
| 插入/更新开销 | 较高(需维护数据物理顺序) | 较低 |
clustered Index 的特点:
-
数据存储即索引(数据和索引一体)
- b+ 树的叶子节点存放的是整行数据。
- 表的数据物理上按聚簇索引的顺序存储。
-
每张表只能有一个聚簇索引
因为数据只能有一个物理顺序。
-
默认以主键作为聚簇索引。
如果没有主键,会选择第一个唯一非空的索引,或自动生成隐藏的rowid。
-
访问速度快(主键访问)
查询主键时直接从叶子节点获取整行,无需回表。
Secondary Index 的特点:
-
索引与数据分裂(索引存储指针)
叶子节点存放的是主键值的引用(InnoDB中)而不是整行数据。
-
可以有多个非聚簇索引
可以按需为不同字段创建索引。
-
查询时通常需要“回表”
先通过索引定位主键,再用主键到聚簇索引中找出整行数据。
-
适用于非主键字段的查找和排序
21 聚簇索引 vs 非聚簇索引在 CRUD 中的区别
| operate | Clustered Index | Secondary Index |
|---|---|---|
| Read | 主键查找块,无需回表 | 需回表,除非使用覆盖索引 |
| Create | 主键连接则快,主键随机插入成本高。 | 每插入一条记录需要更新多个非聚簇索引 |
| Update | 更新主键代价高,相当于删除+插入 | 更新索引字段需维护对应索引 |
| Delete | 删除主键数据快,涉及页合并 | 需删除所有有关联的非聚簇索引项,成本更高 |
Practical Advice
- 使用自增主键作为聚簇索引:提高插入性能。
- 频繁查询的字段考虑做覆盖索引,减少回表。
- 对于更新频繁的字段,不建议建立索引。
- 避免过多索引,影响插入/更新/删除性能。
- Read (查询)
-
聚簇索引
- 查询主键非常快:数据直接在B+树叶子节点中,无需回表。
- 范围查询效率高:数据有序排序,可顺序扫描。
-
非聚簇索引
- 查询非主键字段需要 先查索引,再回表(回到聚簇索引)。成本高。
- 若使用 覆盖索引 (即查询字段都在非聚簇索引中),可避免回表。
select username from users where username = 'Lily'
- Create(插入)
-
聚簇索引
- 插入主键值较小的数据通常比较快,(比如自增主键)
- 若主键值随机(如 UUID),插入会频繁导致 页分裂、移动数据快、性下降。
-
非聚簇索引
- 插入记录时,需要先更新聚簇索引,再更新所有非聚簇索引中的键值引用。
- 非聚簇索引越多,插入越慢。
- Update(更新)
-
聚簇索引
- 更新非索引字段,仅影响数据本身,成本较低。
- 更新聚簇索引字段(主键)时,会触发数据迁移,相当于删除+插入
-
Secondary Index
- 若更新字段是非聚簇索引中的列,需要同步更新该索引。
- 频繁更新索引字段,会引发频繁的 B+ 树调整。
- Delete(删除)
-
Clustered Index
- 删除主键记录时,直接找到叶子节点删除数据,较高效。
- 数据实际物理删除可能依赖于页合并机制或延迟回收。
-
Secondary Index
- 删除记录时,不仅要删除主sh,还需清除所有相关的非聚簇索引项。
- 索引越多,删除操作成本越高。
22 为什么 InnoDB 的非聚簇索引不存物理地址而是主键值?
原因一:数据页可能移动,但主键不会变
原因二:简化一致性和崩溃恢复
原因三:兼容性强,支持压缩表、行格式变化等特性
原因四:降低碎片与锁管理复杂性
| 使用主键作为引用优势 | |
|---|---|
| 数据页变化 | 主键不会变,引用稳定 |
| 系统崩溃恢复 | 主键逻辑地址便于恢复 |
| 兼容性 | 各种表格式下均通用 |
| 索引维护成本 | 插入/更新只改主键索引指针 |
| 锁粒度控制 | 更利于范围锁,行锁 |