SQL 优化(三):使用覆盖索引

摘要

今天跟大家分享一个比较常见的 SQL 优化手段——使用覆盖索引。需要特殊说明的是,MySQL 支持多种存储引擎,对索引的支持也不同,这里我们只关注 InnoDB 引擎的 BTree 索引

InnoDB 的索引实现

在介绍覆盖索引之前,我们先简单的聊一聊 InnoDB 的索引实现,InnoDB 的数据文件本身就是索引文件,表结构就是按 B+ Tree 组织的一个索引结构,树的叶子结点的 data 域保存了完整的数据记录,这个节点的 key 是表的主键

除了主键索引外,其他索引的叶子结点的 data 域,不会保存完整的数据记录,而是将主键作为其 data 域

总结一下,InnoDB 表的数据是保存在主键索引中的,其他索引(辅助索引)的叶子结点存储的是记录的主键

分析 SQL 的执行流程

知道了 InnoDB 的索引实现之后,再来看看下面这条 SQL 的执行流程

select * from t_test where k between 3 and 5

下面是t_test表的初始化语句

CREATE TABLE t_test (id INT PRIMARY KEY,k INT NOT NULL DEFAULT 0,v VARCHAR(50) DEFAULT NULL,INDEX k(k) using btree
)  ENGINE=INNODB charset utf8mb4;insert into t_test values(100,1,'a');
insert into t_test values(200,2,'b');
insert into t_test values(300,3,'c');
insert into t_test values(500,5,'e');
insert into t_test values(600,6,'f');

执行流程如下:

  1. k索引树中,根据k=3索引到对应的记录,并取得id=300
  2. 再到id索引(主键索引)中,根据id=300,找到对应的行数据R3
  3. k索引中,找到下一个值k=500,取得id=500
  4. 再到id索引中,根据id=500,找到对应的行记录R5
  5. 最后到k索引中,找到下一个值,k=6,不满足 where 条件,查找结束

在这个过程中,k索引是辅助索引,只保存了行记录的主键,如果要取得对应行的整行记录,就需要回到主键索引中进行搜索。这个回到主键索引中进行搜索的过程,称之为回表

使用覆盖索引优化 SQL

如果我们执行的语句是

select id from t_test where k between 3 and 5

由于只需要查id的值,而id的值已经记录在k索引树上了,所以无需再进行回表操作,也就是说,在这个查询里面,k索引树已经覆盖了我们的查询需求,我们称之为覆盖索引

由于覆盖索引减少了回表的过程,所以可以显著提高 SQL 的执行效率,所以使用覆盖索引是一种常见的优化手段

基于覆盖索引的思想,假设有下面这种场景,我们需要根据手机号查询用户的姓名,用户表的定义如下:

CREATE TABLE `t_user` (`user_id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) DEFAULT NULL,`sex` tinyint(1) DEFAULT NULL,`mobile` varchar(45) DEFAULT NULL,`create_time` datetime DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`user_id`),KEY `idx_mobile` (`mobile`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4

我们的 SQL 这样写

select username from t_user where mobile = '15622000000';

这时候还是需要进行回表操作,因为idx_mobile索引树上并没有存储 username,这时候,我们可以修改一下idx_mobile索引,将其改为mobileusername的联合索引

ALTER TABLE `tmp`.`t_user` 
DROP INDEX `idx_create_time` ,
ADD INDEX `idx_mobile_username` USING BTREE (`mobile`, `username`);

这样,idx_mobile_username索引树上也有 username 了,就不用进行回表操作了

当然,索引的维护是有代价的,因此,至于使用idx_mobile_username覆盖索引,还是使用idx_mobile进行回表操作,就需要根据实际情况具体分析了

关注公众号:huangxy,一起学习,一起进步

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】MVCC是如何解决快照读下的幻读问题的

文章目录 LBCC当前读 MVCC隐藏列undo logRead View 总结 我们从上文中了解到InnoDB默认的事务隔离级别是repeatable read(后文中用简称RR),它为了解决该隔离级别下的幻读的并发问题,提出了LBCC和MVCC两种方案。其中LBCC解决的是当…

SAP 区分工单BOM物料是手工删除 还是 Teco后自动关闭需求

SAP 区分工单BOM物料是手工删除 还是 Teco后自动关闭需求 首先 resb表删除标识XLOEK 都为 ‘X’,无法通过其它字段直接区分 1先从前台界面区分 手工删除的,组件界面颜色正常,状态为-REL 删除 Teco自动关闭需求的,颜色不一样&am…

MAC电脑使用技巧

Mac打开根目录 /user下的文件 mac 上怎么显示隐藏的/user文件夹,有两种方法可选~~~ 1,Finder界面是,最上方,通过“前往”进入“电脑”或文件夹 先进入到需要显示隐藏文件的文件夹下 接着按Command苹果键F,在窗格上会显示搜索栏 然…

OpenCV(图像处理)-基于Python-轮廓查找

轮廓查找 1. 轮廓2.轮廓查找2.1 findContours()2.2 drawContours()2.3 contourArea()和arcLength()2.4 多边形逼近与凸包approxPolyDP()convexHull()2.5 外接矩形minAreaRect()boundingRect() 1. 轮廓 一个图像中具有相同颜色或强度(灰度图)的连续点所组…

springboot配置https

本身不是一个挺难的东西,但是也踩了很多坑,终于是可以了,在此记录一下。 就两步生成证书和springboot配置。 目录 1.生成证书2.springboot配置3.启动验证注意事项 1.生成证书 这里采用java自带的keytool进行生成。 注意jdk环境,…

最新,2023年6月CDGP设计及论述题解析

2023年6月CDGP设计及论述题解析 (加gzh“大数据食铁兽”,回复“2023cdgp”获取完整版) 酒店会员建模 结合国内外数据安全法律法规,谈谈境外传输数据安全管理体系建设 国内:《数据安全法》、《网络安全法》、2022年9月…

基于深度学习的高精度打电话检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度打电话检测识别系统可用于日常生活中或野外来检测与定位打电话目标,利用深度学习算法可实现图片、视频、摄像头等方式的打电话目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检…

Docker 中的 .NET 异常了怎么抓 Dump

一:背景 1. 讲故事 有很多朋友跟我说,在 Windows 上看过你文章知道了怎么抓 Crash, CPU爆高,内存暴涨 等各种Dump,为什么你没有写在 Docker 中如何抓的相关文章呢?瞧不上吗? 哈哈,在DUMP的分…

SpringBoot 实现 PDF 添加水印

SpringBoot 实现 PDF 添加水印 使用场景方式一:使用 Apache PDFBox 库方式二:使用 iText 库方式三:Free Spire.PDF for JavaDemo 使用场景 PDF(Portable Document Format,便携式文档格式)是一种流行的文件…

Jmeter简单实现登录测试

目录 前言: 1、添加线程组--在测试计划上右击-添加-Threads-线程组 2、添加http请求默认值--在线程组上右击-添加-配置元器件-http请求默认值 3、添加sampler-http请求-登录界面 4、添加sampler-http请求-登录-携带用户名和密码 5、创建存放用户名和密码的文件…

Git:git merge和git rebase的区别

分支合并 git merge是用来合并两个分支的。比如:将 b 分支合并到当前分支。同样git rebase b,也是把 b 分支合并到当前分支。他们的 「原理」如下: 假设你现在基于远程分支"origin",创建一个叫"mywork"的分支…

Golang的trace性能分析

文章目录 一、trace概述二、trace的使用方式代码中trace采集通过pprof采集 三、trace分析细节trace的web界面trace中需要关注的关注GC的频率关注goroutine调度情况关注goroutine的数量理想情况 四、GC分析当前服务GC情况设置GOGC设置GOMEMLIMITGC阈值的讨论GC的特点 五、gorout…