聚簇索引、非聚簇索引与回表

一、聚簇索引(Clustered Index)

核心特点:索引和数据放在一起,叶子节点直接存整行数据。

InnoDB 里,主键索引就是聚簇索引。

  • B+ 树的叶子节点 存放的是完整的一行数据

  • 找到索引,就等于找到了整行,不需要再回表

类比 :像一本字典,正文本身就是按拼音排序的,你按拼音翻到那一页,字和解释都在那一页。

如果没有主键怎么办?

InnoDB 会这样选聚簇索引:

  1. 有主键 → 用主键

  2. 没主键 → 选第一个唯一非空索引

  3. 都没有 → 自动生成一个隐藏的 row_id 做聚簇索引

所以每张 InnoDB 表一定有且只有一个聚簇索引。

二、非聚簇索引(二级索引 / 辅助索引)

核心特点:索引和数据分开,叶子节点存的是主键值,不是整行数据。

除了聚簇索引,你建的其他索引都是非聚簇索引 (也叫二级索引)。

  • B+ 树的叶子节点 存放的是索引列的值 + 主键值

  • 通过二级索引找到的只是主键,不是完整数据

类比 :像书的目录,目录只告诉你"第 100 页",具体内容还得去正文(聚簇索引)里翻。

举例

表 users:

id(主键) name age
1 张三 20
2 李四 25
  • 聚簇索引 (主键 id):叶子节点存 (1, 张三, 20)、(2, 李四, 25)

  • 非聚簇索引 (在 name 上建索引):叶子节点存 (张三, 1)、(李四, 2),只存 name 和主键 id

三、回表(Back to Table)

回表 = 通过二级索引找到主键后,再拿主键去聚簇索引里查一次完整数据。

什么时候会回表

sql 复制代码
SELECT * FROM users WHERE name = '张三';

执行过程:

  1. 走 name 的二级索引,找到 name = 张三 对应的主键 id = 1

  2. 拿 id = 1 去聚簇索引 里查,拿到整行 (1, 张三, 20)

  3. 返回结果

第 2 步就是回表。

怎么判断有没有回表

用 EXPLAIN 看 Extra:

  • 有 Using index → 用了覆盖索引,不回表

  • 只有 Using where,没有 Using index → 可能回表

四、怎么避免回表:覆盖索引

覆盖索引 :查询需要的列,全都在索引里,不用回表。

sql 复制代码
-- 建联合索引
CREATE INDEX idx_name_age ON users(name, age);

-- 查询列都在索引里
SELECT name, age FROM users WHERE name = '张三';
  • 索引 (name, age) 的叶子节点存 (张三, 20, 1)

  • 查询要的 name、age 都在索引里

  • 直接返回,不用回表

EXPLAIN 里会显示 Extra = Using index。

注意 :如果写成 SELECT *,要的列超出了索引范围,就还是要回表。

相关推荐
ss2733 小时前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql
瑞克-桑切斯3 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
z06.4 小时前
MySQL索引
数据库·mysql
考虑考虑4 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin4 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS4 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer4 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源5 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
CCIE-Yasuo7 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶7 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构