MySQL 中什么是回表?

MySQL 回表(覆盖索引之外的查询逻辑)完整讲解

一、什么是回表

前置基础:InnoDB 索引结构

InnoDB 主键索引叫聚簇索引 :

叶子节点 = 完整一行数据(主键+所有字段)。

普通索引(二级索引):

叶子节点 = 「索引列值 + 主键ID」,不存完整行数据。

回表定义

当SQL使用普通二级索引 查询,但SELECT/WHERE需要的字段不在二级索引里时:

  1. 先通过二级索引找到满足条件的主键ID;
  2. 拿着主键ID再去主键聚簇索引 中查询完整行数据;
    这个第二次查表拿全字段 的过程,就叫回表。

举个例子

表 t_fund,主键 id,普通索引 idx_product_code(product_code)

sql 复制代码
-- 会回表
SELECT product_name, net_value FROM t_fund WHERE product_code = '001';

执行流程:

  1. 在 idx_product_code 找到 product_code='001',拿到主键 id=1001;
  2. 根据 id=1001 去主键索引读取 product_name、net_value;
    第二步操作就是回表。

无回表(覆盖索引)

如果索引包含查询全部字段,不需要二次查表,叫索引覆盖,不会回表:

sql 复制代码
CREATE INDEX idx_product ON t_fund(product_code,product_name,net_value);
SELECT product_name, net_value FROM t_fund WHERE product_code = '001';

只走二级索引,一次查询完成,无回表。

二、为什么会产生回表(不是"要用",是查询逻辑必然产生)

很多人误区:不是主动要用回表,是缺少覆盖索引时自动发生,产生的原因:

  1. 查询字段超出二级索引存储范围
    二级索引只存索引列+主键,查其他业务字段必须回主键索引拿数据;
  2. 仅创建单列普通索引,未做联合覆盖索引
    金融业务经常查多字段,单列索引必然触发回表;
  3. 使用 SELECT * 查询所有字段
    无论什么二级索引,* 一定会触发回表。

三、回表带来的问题(业务开发重点关注)

  1. 性能损耗,翻倍IO
    两次索引树查找,IO次数翻倍;大数据量、日终估值批量查询会明显变慢;
  2. 大分页、批量统计场景效率暴跌
    比如估值报表批量查询持仓数据,大量回表会拉长跑批时间;
  3. 高并发接口出现慢SQL,引发锁、超时、连接池耗尽。

四、开发中怎么规避/优化回表(金融资管平台实用方案)

  1. 杜绝 select *,只查询需要的字段;
  2. 创建联合覆盖索引,把查询条件、返回字段全部放进索引;
  3. 统计类、报表类SQL优先设计覆盖索引,消除回表;
  4. 复杂汇总查询可使用临时表、物化视图提前聚合,减少实时回表查询。

五、结合你的金融资产管理平台场景举例

场景:根据产品代码查询基金净值、产品名称、持仓规模(估值报表常用)

  • 只建单列索引 product_code:每次查询都回表,亿级资产数据跑批卡顿;
  • 建立覆盖索引 idx_pdt_code(product_code,product_name,net_value,scale):直接消除回表,批量估值、报表查询速度大幅提升。

六、补充区分

  1. 主键索引查询:永远不会回表,直接拿到完整行;
  2. 二级索引+字段不全:必然回表;
  3. 二级索引包含全部查询字段:覆盖索引,无回表。
相关推荐
星光开发者15 小时前
基于springboot智慧草场牛羊管理系统-计算机毕设【课程设计】50360
vue.js·spring boot·后端·mysql·php·课程设计·express
悟天特斯15 小时前
边缘计算的“实时决策“:从数据回传到边端即时推理的决策升级
数据库·人工智能·边缘计算
这个DBA有点耶15 小时前
分布式集群的“最后一公里”:分片集群与透明分布式集群的工程代价拆解
数据库·分布式·架构
猫咪很可爱16 小时前
MySQL 视图与只读用户:安全查询的完整实践指南
数据库·sql·mysql
l1t16 小时前
测试用go语言执行脚本把数据保存到SQLite数据库
数据库·golang·sqlite
猫咪很可爱16 小时前
MySQL 5.7 备份恢复后函数与存储过程丢失:原因分析与正确备份姿势
数据库·mysql·bug·shell
GottdesKrieges16 小时前
Redis哨兵模式新建用户和修改口令
数据库·redis
二宝哥17 小时前
02.springboot项目对接国内模型实现对话聊天
数据库·人工智能·spring boot
秦时明月之君临天下17 小时前
MySQL purge 参数详解:innodb_purge_threads 与 innodb_purge_batch_size
数据库·mysql·1024程序员节
三垣网安17 小时前
某某大学心理健康教育平台弱口令及SQL注入漏洞
数据库·sql