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 ...
随机推荐
- IDEA maven项目报错,找不到或无法找到主类
最近在写UDF,依赖复制的公司的依赖, <dependency> <groupId>org.apache.hive</groupId> <artifactId ...
- Elasticsearch java api操作(一)(Java Low Level Rest Client)
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
- Linux sed 命令总结
一.sed格式命令 sed 命令行格式为:sed [选项] 'command' 输入文本 二.sed命令的选项 sed [选项] [动作] 选项与参数: -n :使用安静(silent)模式.在一般 ...
- 两个很赞的用法(count函数里的表达式+计算时间间隔)
1.count函数里写表达式 #无效写法,这样写不会判断表达式(ischecked=0),会全部列出来 SELECT cardid FROM search_detail GROUP BY cardid ...
- 【Nginx学习笔记】-初识Nginx
Nginx 目录 Nginx Nginx 特点 Nginx 基本功能 Nginx 使用场景 Nginx 安装/卸载 Docker 方式运行 Ubuntu上安装 卸载Nginx Nginx 命令 Ngi ...
- halcon案例学习之cbm_label_simple
*cbm_label_simple 程序说明:*这个示例程序展示了如何使用基于组件的匹配来定位复合对象.在这种情况下,应该在图像中找到一个标签,用户既不知道其中的组件,也不知道它们之间的关系.因此,创 ...
- linux + svn提交日志不能显示 日期一直都是1970-01-01
网上很多都是说将svn安装目录下的svnserve.conf文件中的anon-access 设置为read,但是 经查阅并测试, 设置为: anon-access = none 是正确的,设置成 r ...
- vmstat参数详解
vmstat 5 可以使用ctrl+c停止vmstat,可以看到输出依赖于所用的操作系统,因此可能需要阅读一下手册来解读报告 第一行的值是显示子系统启动以来的平均值,第二行开始展示现在正在发生的情况, ...
- DataGridView控件使用Demo
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- SVM 支持向量机算法-实战篇
公号:码农充电站pro 主页:https://codeshellme.github.io 上一篇介绍了 SVM 的原理和一些基本概念,本篇来介绍如何用 SVM 处理实际问题. 1,SVM 的实现 SV ...