Multi Range Read与Covering Index是如何优化回表的?

上篇文章末尾我们提出一个问题:有没有什么办法可以尽量避免回表或让回表的开销变小呢?

本篇文章围绕这个问题提出解决方案,一起来看看MySQL是如何优化的

回表

为什么会发生回表?

因为使用的索引并没有整条记录的所有信息,因此使用索引后不满足查询列表需要的列,就要回表查询聚簇索引

image.png

回表查询聚簇索引时,由于主键值是乱序的这样就会导致随机IO

什么是随机IO呢?

MySQL查询时,需要将磁盘的数据加载到缓冲池中,与磁盘交互的单位是页,页中存在多条记录

由于获取的是聚簇索引的页,那么该页中的主键值是有序的,但在二级索引上的记录主键值可能并不是有序的

image.png

比如图中第一条记录主键值为24记录在页A中,第二条记录主键值为82546记录在页C中

当遍历到第一条记录时需要去加载页A,当遍历下一条记录时需要去加载页C

当这种随机IO过多时,可能每查一条记录相当于要去加载一个页,成本非常大

不要小瞧回表的开销,当查询数据量大,使用二级索引都要回表的话,性能还不如全表扫描(扫描聚簇索引),这通常也是索引失效的一大场景(后续文章再来聊聊这块)

Multi Range Read 多范围读取

那有没有什么办法降低成本呢?

回表成本大的原因主要是产生随机IO,那能不能先在索引上查出多条记录,要回表时对主键值进行排序,让随机IO变成顺序IO呢

对主键值排序后每个加载的页,页中可能存在多条需要回表查询的记录就减少回表随机IO的开销

MySQL中另一个优化回表的手段是:Multi Range Read 多范围读取 MRR

MRR使用缓冲区对需要回表的记录根据主键值进行排序,将随机IO优化为顺序IO

image.png

使用MRR优化后图中第二条记录id为25回表时就可以直接在缓冲池的页A中获取完整记录

查看MRR缓冲池大小show variables like '%read_rnd_buffer_size%';

可以使用查看相关优化器的参数SHOW VARIABLES LIKE 'optimizer_switch';

有关MRR的优化器开关参数:mrrmrr_cost_based

mrr 表示是否开启MRR

MRR还需要在缓冲池中排序的开销,因此并不是所有场景都用MRR,默认情况下启动mrr_cost_based基于成本判断是否要使用MRR

SET optimizer_switch='mrr=on,mrr_cost_based=off';关闭根据成本判断是否用MRR

附加信息携带Using MRR说明使用MRR

image.png

除了将随机IO优化为顺序IO,还有没有什么方式可以降低回表的开销呢?

我们从另一个角度分析,如果减少查询的数据量,是不是也可以减少回表次数,降低回表开销

那如何减少数据量呢?实际上上篇文章说过的ICP就可以减低回表次数

Covering Index 覆盖索引

回表无论如何优化都会存在一定的开销,那有没有可能避免回表呢?

要避免回表问题,那就要知道为什么会回表?

由于使用的二级索引不包含查询需要的字段,因此需要回表查询聚簇索引获取需要的字段

那如果使用的二级索引包含需要的查询字段是不是就避免回表的呢!

因此可以通过修改查询需要的字段select xx1,xx2或 增加二级索引包含的列(变成联合索引)来避免出现回表

注意:如果你想通过增加二级索引的列来避免回表时,需要评估二级索引存在列太多的维护成本

MySQL中的覆盖索引指的是使用二级索引时不需要回表,在执行计划中的附加信息显示Using index

image.png

将查询列表从 * 改为 age,student_name ,使用二级索引时不需要回表

总结

当使用的二级索引不满足查询需要的列时,会进行回表查询聚簇索引获取完整记录

回表不仅需要再查一次聚簇索引,而且在二级索引中主键值可能是乱序的,因此查询聚簇索引会出现随机IO

查询随机IO时可能每条记录都在不同的页中,这会导致每查询一条记录就需要将磁盘中的页加载到缓冲池,随机IO开销很大

优化回表有两种思路:一种是降低回表的开销,另一种是避免回表

Index Condition Push 索引条件下推(上篇文章说的)可以减少回表次数,降低回表的开销

Multi Range Read 多范围读取在某些场景下使用缓冲池排序主机,将读取的随机IO转换为顺序IO,降低回表开销

修改查询需要的字段或者给二级索引上增加列,使用覆盖索引的方式来避免回表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1489568.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql索引解析

索引 1.创建索引的SQL ALTER TABLE tbl_name ADD PRIMARY KEY (col_list); // 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。ALTER TABLE tbl_name ADD UNIQUE index_name (col_list); // 这条语句创建索引的值必须是唯一的。ALTER T…

加入到「圆心学堂」知识星球后,你将获得些什么呢?

大家好呀,我的知识星球上线啦!加入到「圆心学堂」知识星球后,您将获得些什么呢? 1.共50套原创精品图文教程电子书,包含1000篇文章,涵盖主流框架、中间件、分布式和微服务等领域,紧跟行业趋势&a…

怎么培养政府机关的公文写作能力?

AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频百万播放量 公文写作千万不能零起步,你有时间慢慢学习,但领导哪有时间等你慢慢进步啊。 如果问写公文有什么捷径,那就不得不靠「AI写作工具…

XLua 原理分析 三

前面已经介绍了Lua与C#的基础通信原理,和Wrap中间文件的作用。有了前面2篇的基础,大概已经能搞清这块的原理。 为了加深对这块的印象,这里开始正式分析Xlua中的Lua和C#的通信。 一、Lua如何调用CS的过程 lua的初始化代码: pri…

python基础巩固

基本数据类型 可以用isinstance来判断 a111 isinstance(a,int) True数值运算: >>> 2 / 4 # 除法,得到一个浮点数 0.5 >>> 2 // 4 # 除法,得到一个整数 0 >>> 17 % 3 # 取余 2Python 字符串不能被改变。向一个…

vuex学习day02-state状态、严格模式(strict)、mutations、辅助函数mapMutations、actions

4、state状态 (1)作用:提供共享数据 (2)步骤: 1)找到仓库,通过state提供共享数据 报错1?: 解决方式: 找到.eslintrc.js文件,添加一…

LabVIEW操作系列1

系列文章目录 我的记录: LabVIEW操作系列 文章目录 系列文章目录前言五、特殊用法5.1 取值范围表示5.2 对输入值取值范围进行限定5.3 控制多个While循环停止运行。5.4 获取按钮上的文本5.5 获取按钮上的文本【进阶】 六、使用步骤1.引入库2.读入数据 七、其余功能7.…

python+barcode快速生成条形码3-PyQt6微界面(电商条形码生成工具)

背景 继续上一片文章的电商测试小工具,进行了优化 需求 生成条形码之后,可以通过界面方式读取条形码的图片 支持当个条形码快速生成,以及批量导入 csv文件导入 添加微界面图像按钮,方便操作,更像是在实现测试工具的…

AI在Facebook的应用:预见智能化社交的新前景

在数字化时代,社交媒体平台已成为我们生活的重要组成部分,而人工智能(AI)的快速发展正推动着这些平台向更智能、更个性化的方向发展。Facebook,作为全球最大的社交网络平台之一,正不断探索和应用AI技术&…

基于JAVA+SpringBoot+Vue的oa系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、SpringCloud、Layui、Echarts图表、Nodejs、爬…

x64dbg反汇编技术入门学习笔记

EIP EIP是程序下一次要运行地方 寄存器 临时存放数据,按照Intel规定去存放 window API 微软提供的,用户可以操作系统的一些接口,以函数的形式体现 杀软是如何查杀恶意的 镜像地址 实际地址 实际运行后代码的地址 查外部调用段就可以定位到.rdat…

Android Kotlin:协程

目录: 1)协程是什么? 2)协程和线程的关系? 3)协程如何使用?切线程是什么 4)挂起函数是什么? 5)withContext和lanuch的区别在哪里? 6)…

Jenkins的相关概述和安装

Jenkins 1.什么是jenkins Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。耗内存max 2. 为什么使用Jenkins 拉取、编译、打包…

【初阶数据结构】9.二叉树(4)

文章目录 5.二叉树算法题5.1 单值二叉树5.2 相同的树5.3 另一棵树的子树5.4 二叉树遍历5.5 二叉树的构建及遍历 6.二叉树选择题 5.二叉树算法题 5.1 单值二叉树 点击链接做题 代码: /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

探索 Electron:构建用户友好的登录页面流程

Electron是一个开源的桌面应用程序开发框架,它允许开发者使用Web技术(如 HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序,它的出现极大地简化了桌面应用程序的开发流程,让更多的开发者能够利用已有的 Web 开发技能…

安防巡检机器人:守护安全的智能卫士

安防巡检机器人,作为机器人技术在安防领域的杰出应用,是一种集自主导航、智能巡检、环境监测、远程监控等多功能于一体的智能装备。这些机器人通过集成先进的传感器、高清摄像头、智能算法和导航系统等模块,实现了全天候、全方位、自主化的安…

maven项目容器化运行之3-优雅的利用Jenkins和maven使用docker插件调用远程docker构建服务并在1Panel中运行

一.背景 在《maven项目容器化运行之1》中,我们开启了1Panel环境中docker构建服务给到了局域网。在《maven项目容器化运行之2》中,我们基本实现了maven工程创建、远程调用docker构建镜像、在1Panel选择镜像运行容器三大步骤。 但是,存在一个问…

HDU1059——Dividing,HDU1060——Leftmost Digit,HDU1061——Rightmost Digit

目录 HDU1059——Dividing 题目描述 运行代码 代码思路 HDU1060——Leftmost Digit 题目描述 ​编辑​编辑 运行代码 代码思路 HDU1061——Rightmost Digit 题目描述 运行代码(快速幂) 代码思路 HDU1059——Dividing 题目描述 Problem - …

索引(数据库优化)事务

索引 事务 Spring事务管理 上图模拟的异常为运行时异常 加上这个配置之后如果回滚会显示下面异常信息 事务进阶

数模打怪(八)之图论模型

一、作图 图的数学语言描述: G( V(G), E(G) ),G(graph):图,V(vertex):顶点集,E(edge):边集 1、在线作图 https://csac…