当前位置:首页 > 技术分析 > 正文内容

mysql 回表、索引覆盖、最左匹配、索引下推

ruisui884周前 (04-01)技术分析7

版权声明:本文为CSDN博主「java叶新东老师」的原创文章

原文链接:
https://blog.csdn.net/qq_27184497/article/details/119274535

前言

在执行一条sql的时候,在mysql内部都会通过以下四个流程

+--------------+
|  连接器      |   
+--------------+
     \|/
+--------------+
|  分析器      |  
+--------------+
     \|/
+--------------+
|  优化器      | 
+--------------+
     \|/
+--------------+
|  执行器      | 
+--------------+

我们都知道索引其中一个最主要作用就是加快数据的访问,那么回表、索引覆盖、最左匹配、索引下推 都是mysql的内部优化方式,部分的功能是Mysql5.6的版本上推出的,都是针对索引的优化,如果表中没有索引的情况下,那么就不会有这些优化;

回表

首先我们要知道,每建一个索引在数据库底层都会新建一个B+树,也就是说,一个索引对应一个B+树,回表就是你在查询二级索引字段的时候,二级索引的这棵树中存储的是一级索引的键值,通过这个键值再去一级索引的B+树种查询数据,这种查询叫做回表;需要注意的是,只有普通索引才会有回表的情况,如果你不是普通索引的话,是不存在回表的
比如我们有一张user表,将id设为主键,将name字段设为普通索引,sql如下

create table (
 id bigint(20) NOT NULL AUTO_INCREMENT parmary key,
 name varchar(20) comment '姓名',
 age int(3) comment '年龄'
);

sql语句演示

select * from user where name = 'dong'

当数据库在查询上面这条sql时,先去name索引的B+树里面去找对应的字符串dong,叶子节点存储的是对应行的主键id,拿到主键id后再去id索引的B+树找那一行数据,name索引B+树和id主键B+树如下图

覆盖索引

覆盖索引,我们知道索引节点本身其实也是数据,如果我们只需要索引节点数据(只需要索引字段,不需要其他非索引字段),那查询时就可以直接返回索引节点数据,而不需要再回表。

还是这个sql

select id from user where name = 'dong'

因为我们查询列是主键id,name索引的B+树种已经有id的数据了,那我就不需要费那么大劲再去查主键的B+树了

最左匹配

需要明确一点的是,只有组合索引才会有最左匹配,组合所以的B+树如下图

例如我建了个组合索引(a,b,c)。因为A在最左边,如果我只查询where a = ?,那么这种情况也会走索引查询, 这就叫最左匹配

最左匹配还有其他的一些规则,比如当我使用下列sql时索引都会生效

-- where子句几个搜索条件顺序调换不影响查询结果,因为Mysql中有查询优化器,会自动优化查询顺序
select * from table_name where a = '1' and b = '2' and c = '3' 
select * from table_name where b = '2' and a = '1' and c = '3' 
select * from table_name where c = '3' and b = '2' and a = '1' 

--都从最左边开始连续匹配,所以下列sql也用到了索引
select * from table_name where a = '1' 
select * from table_name where a = '1' and b = '2'  
select * from table_name where a = '1' and b = '2' and c = '3'

--如果不连续时,只用到了a列的索引,b列和c列都没有用到 
select * from table_name where a = '1' and c = '3' 

select * from table_name where a like 'As%'; --前缀都是排好序的,走索引查询

select * from table_name where  a > 1 and a < 3  -- 可以对最左边的列进行范围查询

-- 排序时,只要遵循最左匹配原则都会走索引
select * from table_name order by a limit 10;
select * from table_name order by a,b limit 10;

下列的sql查询时走的是全表查询(未使用索引)

-- 这些没有从最左边开始,最后查询没有用到索引,用的是全表扫描 
select * from table_name where  b = '2' 
select * from table_name where  c = '3'
select * from table_name where  b = '1' and c = '3' 

select * from table_name where  a like '%As'//前缀模糊了,走全表查询
select * from table_name where  a like '%As%'//走全表查询

-- 多个列同时进行范围查找时,只有对索引最左边的那个列进行范围查找才用到B+树索引,也就是只有a用到索引,在1<a<3的范围内b是无序的,不能用索引,找到1<a<3的记录后,只能根据条件 b> 1继续逐条过滤
select * from table_name where  a > 1 and a < 3 and b> 1;

select * from table_name order by b,c,a limit 10;// 这种颠倒顺序的没有用到索引

索引下推

索引下推也是只针对联合索引优化,索引下推的优化是为了减少回表次数;因为索引下推是mysql5.6之后才出现的功能,所以我们以下面这条sql为例,分别说明版本5.6之前和5.6之后的区别

select * from user where name like '张%' and age = 10

mysql 5.6之前

第一次查询时先找开头为的name,找到三个id,然后三个id分别回表三次去查询age为10的记录,最后查到2个记录返回给客户端,这是回表次数为3次

mysql 5.6之后

第一次查询时直接找name字段开头为张,并且InnoDB 在 (name,age) 索引内部就判断了 age 是否等于 10,对于不等于 10 的记录,直接判断并跳过。在我们的这个例子中,只需要对 ID1、ID2 这两条记录回表取数据判断,就只需要回表 2 次

mysql 优化在面试时是最常问到的问题,了解这些底层规律有助于我们在回答问题时游刃有余

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3223.html

标签: 查看表索引
分享给朋友:

“mysql 回表、索引覆盖、最左匹配、索引下推” 的相关文章

一套智能停车场收费管理系统设计方案,拓扑图VISIO格式

大家好,我是薛哥。最近VIP会员群的读者咨询停车场管理系统的规划设计方案,今天分享一个模板素材,主要里面的拓扑图可以编辑的,VISIO格式,建议收藏备用。此套完整的Word方案,VIP会员下载!智能停车场收费管理子系统1、系统概述本次停车场管理系统设计纯车牌识别系统,并可在合适的位置设置中央收费点,...

「 VUE3 + TS + Vite 」父子组件间如何通信?

组件之间传值,大家都很熟悉,涉及到 VUE3 +TS 好多同学就无从下手了,所以分享这篇文章,希望看完后提起 VUE3+TS 能够不慌不忙。平时使用的函数如:ref、reactive、watch、computed 等需要先引入才能使用,但是本篇文章介绍的 defineProps、withDefaul...

你感动了吗?佳能超规格镜头 RF 24-105mm F2.8深度测评

如果要你选一支用作多题材创作的挂机镜头,那我相信很多人会选择24-105mm这个焦段的镜头。作为一支可以实现从广角到长焦的变焦镜头,24-105mm有着丰富的焦段选择。只是基于镜头体积以及光学结构上的限制,此前的24-105mm镜头只能恒定在F4的光圈。而佳能打破了这一限制,将实用焦段和恒定光圈完美...

VUE 技术栈

官网链接:https://cn.vuejs.org/什么是vue:渐进式JavaScript 框架vue-cli链接:https://cli.vuejs.org/vue-cli安装:npm install -g @vue/clivue -V创建一个项目:vue create xxxxxx模版语法:文...

基于 vue3.0 小程序拖拽定制

今天给大家分享一个使用Vue3编写的自由DIY小程序页面。mbDIY 一款基于vue3.x构建的可拖拽定制小程序模板。支持新建页面、自由拖拽模块、复制/移动、自定义模块样式等功能。整个项目分为页面、模块、控件三大部分。模块里面的组件可拖拽至主面板区,编辑后保存即可预览效果。快速安装# 克隆项目 gi...

vue.js 双向绑定如何理解,有什么好处!#云南小程序开发

Vue.js 的双向数据绑定是借助于 JavaScript 的一些特性,如对象的属性 getter 和 setter 以及 Vue 的依赖追踪系统实现的。简单来说,双向数据绑定就是数据与视图间的双向通信,也就是说数据的改变会马上反映到视图中,视图的改变也会立刻改变数据。具体来说,当你改变了数据时,视...