mysql:如何利用覆盖索引避免回表优化查询
说到覆盖索引之前,先要了解它的数据结构:B+树。
先建个表演示(为了简单,id按顺序建):
| id | name |
| 1 | aa |
| 3 | kl |
| 5 | op |
| 8 | aa |
| 10 | kk |
| 11 | kl |
| 14 | jk |
| 16 | ml |
| 17 | mn |
| 18 | kl |
| 19 | kl |
| 22 | hj |
| 24 | io |
| 25 | vg |
| 29 | jk |
| 31 | jk |
| 33 | rt |
| 34 | ty |
| 35 | yu |
| 37 | rt |
| 39 | rt |
| 41 | ty |
| 45 | qt |
| 47 | ty |
| 53 | qi |
| 57 | gh |
| 61 | dh |
以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。
非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。
B+树
B+树和B树是mysql索引的常用数据结构,B+树是B树的进一步优化,将上面的表转成图分析一下:

B+树的特点:
1.B+ 树非叶子节点上是不存储数据的,仅存储键值
2.叶子节点的数据是按照顺序排列的
3. B+ 树中各个页之间是通过双向链表连接
聚簇索引和非聚簇索引
B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。
聚簇索引:
以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。
这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。
这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。
非聚簇索引:
以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。
非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。
如何用覆盖索引避免回表
为什么明明用了非主键索引还会回表,简单说就是非主键索引是非聚簇索引,在B+树叶子节点中只保存主键和该非主键索引,一次查询只能查到这两个字段,如果想查三个字段,就必须再查一次聚簇索引,这就是回表。
举个例子,表中新增一个字段age,我们用name建一个索引(非聚簇索引)
| id | name | age |
| 10 | zs | 23 |
| 7 | ls | 54 |
| 13 | ww | 12 |
| 5 | zl | 76 |
| 8 | xw | 23 |
| 12 | xm | 43 |
| 17 | dy | 21 |
select id,name from user where name = 'zs';
能够命中name索引,索引叶子节点存储了主键id,通过name的索引树即可获取id和name,无需回表,符合索引覆盖,效率较高。
select id,name,age from user where name = 'zs';
能够命中name索引,索引叶子节点存储了主键id,但age字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取age字段,效率会降低。
结论:那怎么做才能避免回表呢?很简单,将单列索引(name)升级为联合索引(name,age).
mysql:如何利用覆盖索引避免回表优化查询的更多相关文章
- mysql覆盖索引与回表
mysql覆盖索引与回表 Harri2012关注 62019.07.28 11:14:15字数 1,292阅读 77,322 select id,name where name='shenjian' ...
- 一篇文章讲清楚MySQL的聚簇/联合/覆盖索引、回表、索引下推
迎面走来了你的面试官,身穿格子衫,挺着啤酒肚,发际线严重后移的中年男子. 手拿泡着枸杞的保温杯,胳膊夹着MacBook,MacBook上还贴着公司标语:"加班使我快乐". 面试官: ...
- InnoDB 聚集索引和非聚集索引、覆盖索引、回表、索引下推简述
关于InnoDB 存储引擎的有聚集索引和非聚集索引,覆盖索引,回表,索引下推等概念,这些知识点比较多,也比较零碎,但是概念都是基于索引建立的,本文从索引查找数据讲述上述概念. 聚集索引和非聚集索引 在 ...
- 【MySQL】覆盖索引和回表
先来了解一下两大类索引 聚簇索引(也称聚集索引,主键索引等) 普通索引(也成非聚簇索引,二级索引等) 聚簇索引 如果表设置了主键,则主键就是聚簇索引 如果表没有主键,则会默认第一个NOT NULL,且 ...
- MySQL/MariaDB数据库的索引工作原理和优化
MySQL/MariaDB数据库的索引工作原理和优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际工作中索引这个技术是影响服务器性能一个非常重要的指标,因此我们得花时间去了 ...
- MySQL 优化之 MRR (Multi-Range Read:二级索引合并回表)
MySQL5.6中引入了MRR,专门来优化:二级索引的范围扫描并且需要回表的情况.它的原理是,将多个需要回表的二级索引根据主键进行排序,然后一起回表,将原来的回表时进行的随机IO,转变成顺序IO.文档 ...
- Oracle组合索引与回表
回表 简单来说就是数据库根据索引找到了指定的记录所在行后,还需要根据rowid再次到数据块里取数据的操作. "回表"一般就是指执行计划里显示的"TABLE ACCESS ...
- MySql分区后创建索引加速单表查询和连表查询
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/konkon2012/article/de ...
- mysql数据库-初始化sql建库建表-关联查询投影问题
下面是一个简易商城的几张表的创建方式 drop database if exists shop ; create database shop CHARACTER SET 'utf8' COLLATE ...
随机推荐
- 地图开发笔记(一):百度地图介绍、使用和Qt内嵌地图Demo
前言 Qt在地图方面的研发. 百度地图 介绍 百度的地图分为多个开发,都是在线的(离线的需要自己提取,本篇解说在线地图). 百度地图JavaScript API支持HTTP和HTTPS, ...
- LeetCode150 逆波兰表达式求值
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...
- linux源码安装软件的一般方法
rhel系统貌似安装不了xmgrace,配置的时候居然说要那个M*tif库.百度了一下,需要openmotif库,然后用root账户想要用yum安装一下这个库,搞了好久没搞懂.后面搞明白了,原因竟是因 ...
- python模块详解 | selenium(持续更新中)
目录: 关于selenium Selenium 安装Selenium 安装浏览器驱动 配置环境变量 selenium方法详解 定位元素 元素操作 浏览器操作 鼠标事件 浏览器事件 设置元素等待 多表单 ...
- IDEA 常用的一些 (就几个) 快捷键
快捷键 说明 Ctrl + P 提示类参数 Ctrl + Q 提示类的属性和方法包名 Ctrl + D 复制一行到下一行 Ctrl + F 查找 Ctrl + R 替换 Ctrl + Z 撤销 Ctr ...
- 【Linux】history用法
通过history命令可以查看我们在系统中输入过的命令 history命令的一些常用参数 -c 清空内存中命令历史 -d # 删除指定的历史命令,比如 history -d 100 ,就是删除第1 ...
- JAVA之路_假克隆、浅克隆、深克隆
一.JAVA假克隆 Java中,对于基本类型,可以用"="进行克隆,而对于引用类型却不能简单的使用"="进行克隆,这与JAVA的内存使用空间有关,JAVA在栈中 ...
- uni-app开发经验分享七: 有关列表数据下拉加载方法的解析及记录
在使用uni.request获取后台数据时,我们往往碰到一个问题,列表的懒加载及数据实时更新,这里记录下我制作这类功能的方法. 问题描述:后台返回数据,前端需要进行10个为一组来分页,先显示前10个, ...
- .NetCore 在不同位置添加过滤器
前言 以ParaModelValidateAttribute(参数校验)和ErrorCatch(错误捕捉)为例. 在方法上添加(局部) 这种方式比较灵活 [ParaModelValidate] [Er ...
- 百度文库Word下载器
最近我妈的文库VIP用完了,但还有很多资源要下载,于是我便在网上找下载工具. 总算找到个完美的!(虽然没界面) 既然没界面,那就自己写一个呗! 原作者 该程序的下载和写入部分由地球守卫者制作 原文链接 ...