MySQL 中的回表

回表是 MySQL 查询优化中的一个概念,指的是在使用非聚簇索引查询时,无法直接从索引中获取所需的所有数据,需要通过非聚簇索引查找到主键值,然后再去聚簇索引中根据主键值获取完整数据行的过程。


1. 回表的触发条件

  • 使用了非聚簇索引(也称二级索引、辅助索引)。
  • 查询的列中有部分字段不包含在非聚簇索引的叶子节点中。
  • 查询无法通过覆盖索引优化(即查询涉及的字段不全在索引中)。

2. 回表的实现过程

假设有如下表结构和查询:

CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT,
email VARCHAR(100),
KEY idx_name (name)
);

查询语句:

SELECT age, email FROM users WHERE name = 'Alice';

执行步骤:

  1. 扫描非聚簇索引 idx_name:
  • 在 idx_name 索引的 B+ 树中查找 name = 'Alice' 的记录。
  • 叶子节点中存储的值是主键 id。
  1. 通过主键值回表:

使用 id 到聚簇索引(主键索引)对应的 B+ 树中,找到完整的数据行。

获取 age 和 email 的值。

3. 回表的性能开销

  • 磁盘 I/O:回表可能导致多次随机磁盘读取(如果数据不在内存中)。
  • 查询延迟:需要在聚簇索引和非聚簇索引之间来回跳转,增加查询时间。

4. 如何减少回表

(1)覆盖索引

  • 定义:当查询的所有字段都包含在非聚簇索引中时,MySQL 可以直接从索引中获取数据,无需回表。

  • 优化方式:

    • 在索引中添加查询需要的字段(称为索引覆盖)。

      示例:
    CREATE INDEX idx_name_age_email ON users(name, age, email);

(2)减少查询列

  • 仅查询必要字段,避免不必要的列导致回表。

(3)合理设计表结构

  • 通过优化索引设计,将查询的高频字段优先纳入索引。

5. 聚簇索引与非聚簇索引的关系

  • 聚簇索引:

    • 数据和索引存储在一起,不存在回表问题。
  • 非聚簇索引:
    • 数据和索引分开存储,查询完整数据行时可能需要回表。

6. 总结

术语 描述
回表 从非聚簇索引中查询到主键值后,再访问聚簇索引获取完整数据行的过程。
触发条件 查询涉及的字段不在非聚簇索引中,或查询字段超出索引覆盖的范围。
解决方法 通过覆盖索引、减少查询列或优化表结构等方式,减少回表操作,提升查询性能。

MySQL 中的回表是什么?的更多相关文章

  1. mysql中的回表查询与索引覆盖

    了解一下MySQL中的回表查询与索引覆盖. 回表查询 要说回表查询,先要从InnoDB的索引实现说起.InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Sec ...

  2. mysql中把一个表的数据批量导入另一个表中

    mysql中把一个表的数据批量导入另一个表中   不管是在网站开发还是在应用程序开发中,我们经常会碰到需要将MySQL或MS SQLServer某个表的数据批量导入到另一个表的情况,甚至有时还需要指定 ...

  3. 【mysql】索引 回表 覆盖索引 索引下推

    索引类型 索引类型分为主键索引和非主键索引.(一定要牢记,是怎么存储数据的) 主键索引的叶子节点存的是整行数据.在 InnoDB 里,主键索引也被称为聚簇索引(clustered index). 非主 ...

  4. MySQL中的全表扫描和索引树扫描

    引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...

  5. MySQL中的联结表

    使用联结能够实现用一条SELECT语句检索出存储在多个表中的数据.联结是一种机制,用来在一条SELECT语句中关联表,不是物理实体,其在实际的数据库表中并不存在,DBMS会根据需要建立联结,且会在查询 ...

  6. mysql中如何删除表上的索引?删除索引?

    需求描述: 今天在做SQL的优化的时候,想要把mysql中某个表上的索引删除掉,突然忘记语法了,找到帮助,在此记录下 操作过程: 1.查看表上的索引 show index from ti_o_sms; ...

  7. 用命令从mysql中导出/导入表结构及数据

    在命令行下mysql的数据导出有个很好用命令mysqldump,它的参数有一大把,可以这样查看:mysqldump最常用的:mysqldump -uroot -pmysql databasefoo t ...

  8. mysql中delete的表别名使用方法

    在 mapper.xml 中的 dynamicWhere 动态查询中使用了表别名,Delete 语句引用了动态查询,如下: <delete id="delete" param ...

  9. 你了解MySQL中的多表联合查询吗?

    前言: 多表联合查询,其实就是我们MySQL中的join语句,经常会看到有人说join非常影响性能,不建议使用,你知道这是为什么呢?我们究竟可不可以用呢? 测试数据: CREATE TABLE `t2 ...

  10. MySQL中的联表查询与子查询

    0.准备数据 1.内连接:INNER JOIN 2.左连接:LEFT JOIN 3.右连接:RIGHT JOIN 4.USING子句 扩展知识点: 0.表别名的使用: 1.group by的用法 2. ...

随机推荐

  1. .NET Core 中如何构建一个弹性的 HTTP 请求机制?

    1. 理解弹性 HTTP 请求机制 什么是弹性? 弹性是指系统在面对故障或异常情况时,能够保持或快速恢复到正常状态的能力.在 HTTP 请求的上下文中,弹性意味着当请求失败时,系统能够自动采取一系列措 ...

  2. 抽取网易云音乐热门评论:html+css+python+js 音乐与灵魂的碰撞

    抽取网易云音乐热门评论:html+css+python+js 音乐与灵魂的碰撞 代码链接 不说废话,上代码!!! get.py # get.py import urllib.request impor ...

  3. 《SpringBoot》EasyExcel实现百万数据的导入导出

    24年11月6日消息,阿里巴巴旗下的Java Excel工具库EasyExcel近日宣布,将停止更新,未来将逐步进入维护模式,将继续修复Bug,但不再主动新增功能. EasyExcel 是一款知名的 ...

  4. java线上问题跟踪工具Arthas的第一次使用

    Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load.内存.gc.线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参.异常,监测方法执行耗时 ...

  5. 注册全局组件(H5) 任意页面使用

    在view下创建components文件夹. 在components下创建文件夹base. base文件夹是用来存放 基础组件的. 比如说页面中很多处都在使用的公共组件 如你需要自定义的按钮 在com ...

  6. 2021 OWASP TOP 10

    OWASP TOP 10 2021年版Top 10有哪些变化? 2021年版Top 10产生了三个新类别,原有四个类别的命名和范围也发生了变化,且进行了一些 整合. 2017年 TOP 10 top ...

  7. Linux 部署DVWA靶场

    Linux 部署DVWA靶场 DVWA是一款开源的网络安全漏洞实践平台,专为安全学习者设计.它涵盖了XXS.SQL注入.文件上传.文件包含.CSRF和暴力破解等多种安全漏洞环境,每个漏洞都有从简单到复 ...

  8. [虚拟化/Docker] Docker Desktop 安装与使用

    0 序:DeepSeek 等AI大模型在Windows的私有化部署 DeepSeek 等AI大模型在Windows的私有化部署,最流行的开源AI终端应用----Dify,依赖于 Docker 环境.由 ...

  9. OpenLayers 4326地图 根据距离设置地图分辨率

    问题:给一个距离,如何确定4326地图缩放等级或者分辨率使地图视口范围为这个距离 我本来打算计算从地图视口左上角到右下角的距离来计算地图缩放的,然后发现不好算,我也不会算,于是就计算水平方向距离的缩放 ...

  10. C#中的StreamWriter和"谁创建谁释放"原则

    C# 类库中的 StreamWriter 类在释放时会同时关闭其所依赖的基础流对象,这是为了确保所有缓冲数据都被写入基础流中,并且在不再需要 StreamWriter 对象时,基础流对象也能够被及时释 ...