聚簇索引和非聚簇索引的区别
1. 什么是聚簇索引(Clustered Index)
InnoDB 中:
PRIMARY KEY(id)对应的索引就是聚簇索引。
特点:
数据和索引存储在一起。
例如:
主键索引(B+Tree) 10 / \ / \ 5 20 叶子节点: 1 -> 用户1完整数据 2 -> 用户2完整数据 3 -> 用户3完整数据叶子节点保存:
整行数据例如:
id=1,name=Tom,age=18聚簇索引特点
叶子节点:
存放完整记录所以:
select * from user where id = 1;过程:
主键索引 ↓ 定位叶子节点 ↓ 获得完整数据只查一次树。
2. 什么是非聚簇索引(二级索引)
例如:
create index idx_name on user(name);这是普通索引。
又叫:
Secondary Index 二级索引 辅助索引叶子节点存什么?
不是完整数据。
而是:
索引列 + 主键值例如:
Tom -> 1 Jack -> 2 Lucy -> 3这里:
1、2、3其实就是:
主键ID3. 查询过程区别
假设:
select * from user where name='Tom';第一步
先查普通索引:
idx_name Tom -> 1得到:
id = 1第二步
再去主键索引查:
id = 1找到:
完整行数据整个过程:
普通索引 ↓ 获取主键id ↓ 主键索引 ↓ 获取数据这个过程叫:
回表(Back To Table)
4. 为什么会有回表
因为二级索引叶子节点没有保存完整数据。
只保存:
索引列 + 主键值例如:
Lucy -> 3数据库拿到:
id=3之后必须:
再查一次聚簇索引获取:
name age address ...5. 什么情况不会回表
例如:
select id,name from user where name='Tom';二级索引:
name + id已经包含:
id name需要的数据都在索引里。
无需再查主键树。
这叫:
覆盖索引(Covering Index)
执行计划:
EXPLAIN会看到:
Using index说明:
没有回表6. 聚簇索引和非聚簇索引对比
| 对比项 | 聚簇索引 | 非聚簇索引 |
|---|---|---|
| 数量 | 只能一个 | 可以多个 |
| 对应 | 主键索引 | 普通索引、唯一索引 |
| 叶子节点 | 完整数据 | 主键值 |
| 查询次数 | 一次 | 两次(回表) |
| 查询速度 | 更快 | 稍慢 |
| 是否回表 | 不会 | 可能会 |
| 存储顺序 | 按主键顺序 | 按索引列顺序 |
7. 为什么只能有一个聚簇索引
因为:
数据只能按照一种顺序存储例如:
数据按:
id排序存储:
1 2 3 4 5那就不可能同时按:
name排序存储:
Jack Lucy Tom因此:
聚簇索引只能有一个而:
普通索引可以有很多个因为它们只是额外维护的B+Tree。
面试标准答案
InnoDB 中主键索引是聚簇索引,其叶子节点存储完整数据记录,因此通过主键查询时只需查一次 B+Tree 即可获取数据。
普通索引属于非聚簇索引(二级索引),其叶子节点存储的是索引列和主键值,而不保存完整数据。查询时先通过二级索引找到主键,再通过主键索引获取完整记录,这个过程称为回表。
如果查询字段全部包含在二级索引中,则可以直接返回结果,形成覆盖索引,避免回表,提高查询性能。
由于数据只能按一种物理顺序存储,因此一个表只能有一个聚簇索引,但可以有多个非聚簇索引。
