
MySQL 中聚簇索引和非聚簇索引的核心区别在于数据是否与索引物理绑定:聚簇索引的叶子节点直接存整行数据,而非聚簇索引的叶子节点只存主键值(或指针),查数据要多走一步。
聚簇索引:数据即索引,表即B+树叶子
在 InnoDB 中,聚簇索引就是主键索引(没主键则选唯一非空索引,再不行就用隐藏的 GEN_CLUST_INDEX)。它的 B+ 树叶子节点不是“指向”数据,而是直接存放完整行记录。这意味着:
- 表数据的物理存储顺序 = 主键逻辑顺序
- 按主键查(如
WHERE id = 100)一次定位,无需回表 - 范围查询(如
WHERE id BETWEEN 100 AND 200)效率高,因数据连续、I/O 少 - 每个表仅能有一个聚簇索引——数据只能按一种顺序落盘
非聚簇索引:索引是目录,查数据要“翻页”
也叫二级索引或辅助索引,比如对 name 或 email 建的索引。它的 B+ 树叶子节点不存行数据,只存索引列值 + 对应主键值。所以:
- 查
WHERE name = 'Alice'先走 name 索引找到主键id=123 - 再拿
id=123回到聚簇索引里查完整行——这个过程叫回表 - 若只查索引列本身(如
SELECT name FROM user WHERE name = 'Alice'),可直接命中叶子节点,称为覆盖索引,不用回表 - 一张表可建多个非聚簇索引,但每个都会额外占用空间并拖慢写入
关键差异对比:回表、存储、性能
真正影响查询表现的三个硬指标:
- 是否回表:聚簇索引查主键必不回表;非聚簇索引查非索引列几乎一定回表
- 存储内容:聚簇索引叶子 = 行数据;非聚簇索引叶子 = (索引列值, 主键值)
- 写入代价:聚簇索引随机插入易引发页分裂(数据重排);非聚簇索引只是追加索引项,更轻量
InnoDB 和 MyISAM 的底层差异
别只看“聚簇/非聚簇”名字,引擎实现完全不同:
- InnoDB:主键 = 聚簇索引;所有二级索引叶子存主键值 → 必须回表
- MyISAM:所有索引都是非聚簇的,但叶子节点存的是数据文件的磁盘偏移量 → 查到地址就直接读,不回表,也不支持事务










