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://xiahunao.cn/news/3267471.html

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

相关文章

Vue3 Pinia/组件通信

2. pinaia 符合直觉的Vue.js状态管理库 集中式状态(数据)管理 官网 2.1 搭建pinaia环境 第一步:npm install pinia 第二步:操作src/main.ts import { createApp } from vue import App from ./App.vue/* 引入createPinia&…

案例分析:人工智能在航空航天领域的应用

作者主页: 知孤云出岫 目录 作者主页:案例分析:人工智能在航空航天领域的应用引言人工智能在航空航天中的主要应用案例分析案例一:AI优化航天器设计案例二:AI辅助飞行安全——预测维护案例三:AI自动驾驶系统案例四:A…

关键词查找【Boyer-Moore 算法】

1、【Boyer-Moore 算法】 【算法】哪种算法有分数复杂度?- BoyerMoore字符串匹配_哔哩哔哩_bilibili BM算法的精华就在于BM(text, pattern),也就是BM算法当不匹配的时候一次性可以跳过不止一个字符。即它不需要对被搜索的字符串中的字符进行逐一比较,而…

探索算法系列 - 滑动窗口

目录 长度最小的子数组(原题链接) 无重复字符的最长子串(原题链接) 最大连续1的个数 III(原题链接) 将 x 减到 0 的最小操作数(原题链接) 水果成篮(原题链接&#x…

第六章:支持向量机

目录 6.1 间隔与支持向量 6.2 对偶问题 6.3 核函数 6.4 软间隔与正则化 6.4.1 软间隔 6.4.2 正则化 6.5 支持向量回归 6.6 核方法 6.1 间隔与支持向量 分类学习最基本的想法就是基于训练集D在样本空间中找到一个划分超平面,将不同类别的样本分开.但能将训练样本分开的…

【宝藏系列】模/数转换十大常用滤波算法

【宝藏系列】模/数转换十大常用滤波算法 文章目录 【宝藏系列】模/数转换十大常用滤波算法👨‍🏫ADC(Analog-to-Digital Converter,模数转换器)1️⃣限幅滤波法2️⃣中位值滤波法3️⃣算术平均滤波法4️⃣递推平均滤波…

PLC通过IGT-SER系列智能网关快速实现WebService接口调用案例

IGT-SER系列智能网关支持PLC设备数据对接到各种系统平台,包括SQL数据库,以及MQTT、HTTP协议的数据服务端;通过其边缘计算功能和脚本生成的工具软件,非常方便快速实现PLC、智能仪表与WebService服务端通信。 本文是通过智能网关读取…

Ubuntu 22.04.4 LTS (linux) GoAccess 分析 Nginx 日志

1 安装goaccess sudo apt-get update sudo apt-get install goaccess 2 控制台运行 goaccess -a -d -f /usr/local/openresty/nginx/logs/access.log -p /etc/goaccess/goaccess.conf #sudo vim /etc/goaccess/goaccess.conf time-format %H:%M:%S date-format %d/%b…

van-dialog 组件调用报错

报错截图 报错原因 这个警告表明 vue 在渲染页面时遇到了一个未知的自定义组件 <van-dialog>&#xff0c;并且提示可能是由于未正确注册该组件导致的。在 vue 中&#xff0c;当我们使用自定义组件时&#xff0c;需要先在 vue 实例中注册这些组件&#xff0c;以便 vue 能…

Emacs之解决无法输入中文问题(一百四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

基于YOLO8的目标检测系统:开启智能视觉识别之旅

文章目录 在线体验快速开始一、项目介绍篇1.1 YOLO81.2 ultralytics1.3 模块介绍1.3.1 scan_task1.3.2 scan_taskflow.py1.3.3 target_dec_app.py 二、核心代码介绍篇2.1 target_dec_app.py2.2 scan_taskflow.py 三、结语 在线体验 基于YOLO8的目标检测系统 基于opencv的摄像头…

Provisional headers are shown Learn more

Provisional headers are shown Learn more 目录 Provisional headers are shown Learn more 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医…

什么情况下的网站要使用CDN加速呢?

CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。 CDN的通俗理解就是网站加速&#xff0c;CPU均衡负载&#xff0c;可以解决跨运营商&#xff0c;跨地区&#xff0c;服务器负载能力过低&#xff0c;带宽过少等带来的网站打开速度慢等问题。 原理就是在客户端…

如何解除maven打包编译的警告日志:[WARNING] 未与 -source 21 一起设置系统模块的位置

在用jdk较高的版本进行maven项目的打包编译时&#xff0c;经常遇到类似“[WARNING] 未与 -source 21 一起设置系统模块的位置”这样的警告日志&#xff0c;如下&#xff1a; 网上大量搜索该问题的解决方案&#xff0c;却未果&#xff0c;无耐去看了官网的用法&#xff0c;才获得…

Java项目中整合多个pdf合并为一个pdf

一、Java项目中整合多个pdf合并为一个pdf gitee笔记路径&#xff1a;https://gitee.com/happy_sad/drools一、依赖导入 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.6</version> …

ts 下使用 interactjs 的时候,事件类型该如何定义 InteractEvent

ts 下使用 interactjs 的时候&#xff0c;事件类型该如何定义 InteractEvent 一、问题 interactjs 是一个很好用的给元素添加拖动事件的插件&#xff0c;它可以实现如下的效果。 其官网是 https://interactjs.io/ vitetsvue3 项目中用到了 interactjs 这个库&#xff0c;但在…

事务、函数和索引

M y S Q L 事 务 什么是事务&#xff1f; 事务&#xff08;Transaction&#xff09;&#xff0c;就是将一组SQL语句放在同一批次内去执行&#xff0c;如果一个SQL语句出错&#xff0c;则该批次内 的所有SQL都将被取消执行。 特点&#xff1a;一个事务中如果有一个数据库操作…

【Android】数据存储方案——文件存储、SharedPreferences、SQLite数据库用法总结

文章目录 文件存储存储到文件读取文件 SharedPreferences存储存储获取SharedPreferences对象Context 类的 getSharedPreferences() 方法Activity 类的 getPreferences() 方法PreferenceManager 类中的 getDefaultSharedPreferences() 方法 示例 读取记住密码的功能 SQLite数据库…

学习OCR具体使用

暂时找了三种&#xff0c;有一些问题待解决 Tesseract-OCR1. 安装库&#xff1a;2. 安装Tesseract-OCR&#xff1a;3. 安装中文语言包&#xff1a;4. Python代码&#xff1a;5. 运行结果 cnOCR1. 安装cnOCR&#xff1a;2. 使用cnOCR进行OCR&#xff1a;3. 运行结果 PaddleOCR1.…

vue 实战 区域内小组件元素拖拽 示例

<template><div><el-button type"primary" click"showDialog true">快捷布局</el-button><el-dialog title"快捷布局配置" :visible.sync"showDialog"><el-row :gutter"20"><el-co…