mysql 回表查询优化_MySQL优化:如何避免回表查询?什么是索引覆盖?

转自:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962609&idx=1&sn=46e59691257188d33a91648640bcffa5&chksm=bd2d092d8a5a803baea59510259b28f0669dbb72b6a5e90a465205e9497e5173d13e3bb51b19&mpshare=1&scene=1&srcid=&sharer_sharetime=1564396837343&sharer_shareid=7cd5f6d8b77d171f90b241828891a85f&key=abd60b96b5d1f2e52ca45314fb2c95a67fad7a457fe265562eb51a1c026389d3f28c52359f96e920368ab44a5d08ebcbbe2ded474be2ba70731ed8b5dcc5dd68cc0eceb4989a74fb04e5055c78af8d38&ascene=1&uin=MTAwMjA4NTM0Mw%3D%3D&devicetype=Windows+7&version=62060739&lang=zh_CN&pass_ticket=tXA4xc7SZYamLpGZz5B6JwJa1ZRvZ4bRlmzFhXwEKeOfloPLulU0O80gsIQUiONb

正式讲解:

数据库表结构:

1 create table user(2 id int primary key,3 name varchar(20),4 sex varchar(5),5 index(name)6 )engine=innodb;

多查询了一个属性,为何检索过程完全不同?

什么是回表查询?

什么是索引覆盖?

如何实现索引覆盖?

哪些场景,可以利用索引覆盖来优化SQL?

这些,这是今天要分享的内容。

画外音:本文试验基于MySQL5.6-InnoDB。

一、什么是回表查询?

这先要从InnoDB的索引实现说起,InnoDB有两大类索引:

聚集索引(clustered index)

普通索引(secondary index)

InnoDB聚集索引和普通索引有什么差异?

InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引:

(1)如果表定义了PK,则PK就是聚集索引;

(2)如果表没有定义PK,则第一个not NULL unique列是聚集索引;

(3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引;

画外音:所以PK查询非常快,直接定位行记录。

InnoDB普通索引的叶子节点存储主键值。

画外音:注意,不是存储行记录头指针,MyISAM的索引叶子节点存储记录指针。

举个栗子,不妨设有表:

t(id PK, name KEY, sex, flag);

画外音:id是聚集索引,name是普通索引。

表中有四条记录:

1, shenjian, m, A

3, zhangsan, m, A

5, lisi, m, A

9, wangwu, f, B

4e64649658b472652588de7eef87ca3a.png

两个B+树索引分别如上图:

(1)id为PK,聚集索引,叶子节点存储行记录;

(2)name为KEY,普通索引,叶子节点存储PK值,即id;

既然从普通索引无法直接定位行记录,那普通索引的查询过程是怎么样的呢?

通常情况下,需要扫码两遍索引树。

例如:

是如何执行的呢?

3119450ce7cc31a54b418b1c6acede66.png

如粉红色路径,需要扫码两遍索引树:

(1)先通过普通索引定位到主键值id=5;

(2)在通过聚集索引定位到行记录;

这就是所谓的回表查询,先定位主键值,再定位行记录,它的性能较扫一遍索引树更低。

二、什么是索引覆盖(Covering index)?

额,楼主并没有在MySQL的官网找到这个概念。

画外音:治学严谨吧?

借用一下SQL-Server官网的说法。

da2caa733c9d26cdcd42b30002d245e3.png

MySQL官网,类似的说法出现在explain查询计划优化章节,即explain的输出结果Extra字段为Using index时,能够触发索引覆盖。

a62bf703a7c0dc4582236a33f57a0e11.png

不管是SQL-Server官网,还是MySQL官网,都表达了:只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。

三、如何实现索引覆盖?

常见的方法是:将被查询的字段,建立到联合索引里去。

仍是之前中的例子:

第一个SQL语句:

0c6eb8b1f89a2da24c82a73e4aec5eec.png

能够命中name索引,索引叶子节点存储了主键id,通过name的索引树即可获取id和name,无需回表,符合索引覆盖,效率较高。

画外音,Extra:Using index。

第二个SQL语句:

cb2e6ad6be14e20465e6d84e09966d0b.png

能够命中name索引,索引叶子节点存储了主键id,但sex字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取sex字段,效率会降低。

画外音,Extra:Using index condition。

如果把(name)单列索引升级为联合索引(name, sex)就不同了。

059f6219b3fc301a4f7fba07e9537f1f.png

可以看到:

都能够命中索引覆盖,无需回表。

画外音,Extra:Using index。

四、哪些场景可以利用索引覆盖来优化SQL?

场景1:全表count查询优化

582a0e64783a955462154b5f9817c532.png

原表为:

user(PK id, name, sex);

直接:

不能利用索引覆盖。

添加索引:

就能够利用索引覆盖提效。

场景2:列查询回表优化

这个例子不再赘述,将单列索引(name)升级为联合索引(name, sex),即可避免回表。

场景3:分页查询

将单列索引(name)升级为联合索引(name, sex),也可以避免回表。

InnoDB聚集索引普通索引,回表,索引覆盖

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

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

相关文章

安装 Windows 自动化 API 3.0 后,Visual Studio 2010 的运行速度更快

安装 Windows 自动化 API 3.0 后,Visual Studio 2010 的运行速度更快 本文适用于以下产品: Microsoft Visual Studio 2010如果未安装 Windows 自动化 API 3.0,则使用 Windows 自动化 API 的应用程序会明显降低 Microsoft Visual Studio Inte…

使用ASP.Net WebAPI构建REST服务(一)——简单的示例

由于给予REST的Web服务非常简单易用,它越来越成为企业后端服务集成的首选方法。本文这里介绍一下如何通过微软的Asp.Net WebAPI快速构建REST-ful 服务。 首先创建一个Asp.Net Web应用程序(我这里用的是Visual Studio 2013,它已经内置了Web AP…

告别花瓶:2015年智能电视路在何方?

智能手机与平板在IT市场风生水起,让几岁小孩到大爷大妈们都对玩手机、平板乐此不彼。曾经辉煌几十年的电视行业,如今又重新融合了智能系统以全新的面貌出现在人们面前。多家互联网企业对这一“翻新”的市场虎视眈眈,并推出了多款智能电视。但…

文件类型

转载于:https://www.cnblogs.com/hlc-123/p/10958326.html

灾备还缺一套评价体系

1月10日,灾备技术产业联盟正式成立。这样一个中立的、由业内众多厂商和大型用户组成的、以服务为宗旨的联盟将为我国灾备技术和应用的规范化发展做出积极贡献。经过一年多的酝酿、历经7次筹备会议,由华为、北京邮电大学、中治研国际信息技术研究院和中国…

DFS知识点

2019-06-01 11:14:34 加油,坚持!!! 1. 2. 3. 转载于:https://www.cnblogs.com/Artimis-fightting/p/10960409.html

Android 反射获取内外置存储卡方法

2019独角兽企业重金招聘Python工程师标准>>> 以前的Android(4.1之前的版本)中,SDcard跟路径通过“/sdcard”或者“/mnt/sdcard”来表示存储卡,而在Jelly Bean系统中修改为了“/storage/sdcard0”,以后可能还会有多个SDcard的情况。…

docker安装mysql redis_Docker安装Mysql和Redis以及构建部署应用镜像

为了方便本地测试项目,为了方便开启新的环境,为了方便部署,打算本地利用Docker安装Mysql和Redis。搭建Springboot项目,编写Dockerfile,打包构建镜像。简单使用docker-compose启动服务。简述docker-compose和K8S。环境系…

Windows 下查看端口占用情况 netstat / tasklist / findstr

为什么80%的码农都做不了架构师?>>> Windows服务器不熟悉很多,尤其是防火墙这块。不过其实和Linux一样,省事的话就是关了就好了。不过对于端口占用还是时常有的,比如QQ音乐,迅雷这些,如果你的电…

2015 年度计划

2019独角兽企业重金招聘Python工程师标准>>> scala -> akka -> sparketcd 使用开源产品 negroni https://github.com/codegangsta/negroni转载于:https://my.oschina.net/kuerant/blog/372981

php透明颜色的代码,PHP imagecolorallocatealpha - 为一幅图像分配颜色和透明度

PHP imagecolorallocatealpha - 为一幅图像分配颜色和透明度imagecolorallocatealpha — 为一幅图像分配颜色和透明度。语法int imagecolorallocatealpha ( resource $image , int $red , int $green , int $blue , int $alpha )imagecolorallocatealpha() 的行为和 imagecolor…

Windows on Device 项目实践 4 - 智能风扇制作

在前面的文章中,我们已经学习并且利用Intel Galileo开发板和Windows on Device制作了火焰报警器、感光灯和PWM调光灯。在这个项目中,我们来利用温度传感器和直流电机,完成一个简单的智能风扇的制作。 1. 温度传感器 LM35 是很常用且易用的温度…

php接口异常,api接口异常怎么办

异常:在程序开发过程中出现的不正常情况,就是异常。比如除数是0,参数为null,调用参数的成员变量或者方法,数组下标越界。异常分为两大类型:(1)Exception:程序员可以解决的:空指针&am…

【吐槽】博客园新的原创文章在搜索引擎的排名不及转载的站点

最近写博客比较多,但发现文章被一些网站转载后,排名比博客园的链接还要高,有些搜索引擎甚至连博客园的链接都没有,坑爹,坑爹。。。 以前博客园的网友也遇到过类似的情况,也分享过一些防转载的经验&#xff…

Qt之程序发布以及打包成exe安装包

一、简述 Qt项目开发完成之后,需要打包发布程序,而因为用户电脑上没有Qt配置环境,所以需要将release生成的exe文件和所依赖的dll文件复制到一个文件夹中,然后再用 Inno Setup打包工具 打包成一个exe安装包,就可以发布了…

使用Nginx+WordPress搭建个人网站

背景 很多研究技术的朋友喜欢写博客。如果希望搭建一个完全属于自己的网站,也并不困难。这里简要分享一下我搭建这个博客网站的经验。 关键步骤 购买服务器、域名、DNS云解析服务网站备案(可选)安装NginxWordPressMySQLPHP配置WordPress运行网…

高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输入时显示一个提示字符串。由于Background对ComboBox无效&#xff0…

RoRoWoBlog 开源博客系统介绍

萝萝窝个人博客开源项目 以Asp.net MVC 2.0 ADO.Net Entity Framework 4.0 Unity 2.0 MvcPager JQuery 等技术框架,开发的个人博客系统。 支持MetaWeblog接口 通过MetaWeblog接口,可以将您个人博客系统中的博文,直接同步到您其它网站的博…

JAVA 面试知识点

主要包括以下几个部分: Java 基础知识点Java 常见集合高并发编程(JUC 包)JVM 内存管理Java 8 知识点网络协议相关数据库相关MVC 框架相关大数据相关Linux 命令相关面试,是大家从学校走向社会的第一步。 互联网公司的校园招聘&…

sqlserver 导出mysql,sqlserver数据(表)导出到mysql

这里说明我的工具: Navicat Premium1 首先 navicat 连接到 sqlserver 数据库,也就是我要从这里导出那个 170 万条数据的表,然后选中表右键单击,选择导出向导2 然后选择文本文件,下一步3 核对下我们要导出的表&#xff…