详解MySQL中一条SQL执行过程

MySQL基本架构

如下图所示,从宏观角度来说MySQL架构可以分为server层和存储引擎层,其中Server层包含如下:

  1. 连接器:进行身份认证和权限相关校验。
  2. 查询缓存:MySQL8.0已废弃,查询缓存主要是用于提高查询效率而加的一层缓存。
  3. 分析器:对SQL执行动作、语法、词法进行分析。
  4. 优化器:对要被执行的SQL进行优化。
  5. 执行器:执行SQL查询语句,然后从存储引擎返回结果。

接下来说说存储引擎,对于MySQL而言存储引擎是支持插拔的,常见的存储引擎有myisam、innodb、memory,而MySQL默认的使用的是innodb。

在这里插入图片描述

详解MySQL各层的工作分工

MySQL客户端和服务端的通信协议

对于MySQL而言,客户端和服务端之间采用的是一种半双工的通信协议,这样就意味着同一时刻要么客户端向服务端发送数据,要么服务端向客户端发送数据。这也就进一步的说明了客户端在接收客户数据的时候必须将服务端发送的数据全部接受完才能断开连接。

这个交互流程也在告诉我们,进行大量数据查询的时候,若无必要尽可能使用limit进行分页查询,避免这种全双工的通信方式导致客户端接收导致资源长时间的占用。

在这里插入图片描述

连接器

主要判断用户登录的账户密码是否正确,如果账户密码都正确,则进行权限查询,注意在本次连接期间只要不断开,无论外界如何修改权限,这个会话的权限都是以连接器查询到的为主。

查询缓存

MySQL8已经废弃的功能,这个功能常用于结果的缓存复用以提高查询性能,例如我们进行select * from table where id=1的查询。第一次发现缓存中没有,就从数据库中查出来并放到缓存中下次可以在复用。
MySQL8之所以废弃是因为数据库中的数据经常更新导致缓存失效,就需要清空这个缓存,这期间和开销是非常没必要的,所以索性废掉这个功能。

分析器

分析器主要是负责sql解析和预处理,它会将客户端发来的查询一句进行解析生成一颗解析树,然后解析器根据自定义规则对sql语句进行词法和语法分析。

  1. 词法分析:分析关键字是否拼写有误,并通过关键字判断这条SQL做什么。
  2. 语法分析:对这条SQL语句的语法进行检查。

优化器

分析器分析无误之后,说明这条语句是可以正常执行的。MySQL优化器就会通过分析找出成本最小的一种方式生成执行计划,交由执行器执行。

对此,我们这里不妨补充一下MySQL能够自己处理的一些优化类型:

  1. 将外连接转为内连接:某些场景之下,我们可能会用到外连接,但是在where或者库表结构的调整之后,我们的左外连接后者右外连接可能不存在null的连接。
    例如下面这段sql,我们对table2进行左外连接,但是我们条件关联之后,table1对应的id值在table2中都有,那么查询优化器可能就会对其进行优化,会将其转换为内连接,更加精确的去匹配索要查询的行避免没必要的扫描。
SELECT *
FROM table1
LEFT JOIN table2
ON table1.id = table2.id;

举个例子,上面的sql如果table1对应的id在table2中都有,那么sql语句就会变成这样

SELECT *
FROM table1
LEFT JOIN table2
ON table1.id = table2.id
WHERE table2.id IS NOT NULL;

然后优化器就会将其优化成这样

SELECT *
FROM table1
inner JOIN table2
ON table1.id = table2.id
WHERE table2.id IS NOT NULL;
  1. 使用代数等价变换规则,例如我们的查询条件是5=5 and a>5,那么MySQL就会将其优化为:a>5,再比如说我们有这样一条SQL,条件语句为(a<b and b=c) and a=5,那么MySQL就会将其优化为: b > 5 and b=c

  2. 优化min、max,对于建立索引的数据表来说,使用索引所在列的进行最大值和最小值查询时,MySQL优化器会将这种sql判定为常数查询,例如笔者建立的下面这张表,我们将table1的id设置为索引。
    然后查询下面这句sql:

SELECT min(id)
FROM table1;

使用explain查看其执行计划,可以看到执行计划显示Select tables optimized away,这就意味查询时它已经将表移除,而是用一个常数查询来代替。

在这里插入图片描述

  1. 预估并转为为常数表达式:最典型的例子就select * from table1 where id=1+2,MySQL优化器就会将其转为select * fromt table1 where id=3
  2. 索引扫描:这个无需多说,当要查询的列都包含在索引中时,无需进行回表查询,避免没必要的IO操作。
  3. 提前终止查询:对于limit查询而言,MySQL优化器会在查询到需要的数据时直接终止查询,还有一些比较特殊的,例如对于某些不可能的条件,MySQL优化器也会提前将其终止,例如我们将tbale1的id设置为主键,然后键入下面这句查询语句。
Select tables optimized away

那么执行计划就会显示Impossible WHERE从而提前终止查询:

在这里插入图片描述

执行器

对用户进行权限校验,若权限校验不通过则报错,然后执行器就会根据优化器优化后的执行计划(这里的执行计划是一个数据结构),执行器根据这个数据结构顺序调用存储引擎提供的API进行数据查询,并将查询结果返回给客户端,从而完成一次完整的SQL查询。

在这里插入图片描述

用两条完整的sql走一遍上述的流程

了解SQL执行过程之后,我们不妨通过一个实际的例子带入一下了解全过程。

查询语句的执行流程

sql如下所示:

select * from table where b=1 and a=2;

按照我们上文所说的过程:

  1. 校验用户账户密码是否正确,查询权限
  2. 查询缓存(mysql8.0之前),若有数据则直接返回,反之下一步
  3. 分析器进行词法、语法分析。
  4. MySQL优化器进行优化,以本SQL为例,假如我们创建了一个联合索引(a,b),那么优化器就会遵循最左匹配原则将a,b条件进行调换。

在这里插入图片描述

  1. 进行权限校验,若有权限执行器进行查询,将结果从引擎取出返回。

更新语句的执行流程

更新语句我们示例SQL如下:

update table set a=1  where b=1;

步骤还是一样:

  1. 连接器的工作,不多赘述
  2. 查询缓存,若有则直接操作这条数据(mysql8不走这一步)
  3. 分析器的工作,不多赘述
  4. 进行更新操作,首先调用引擎API,将这个修改写入内存中,同时记录redo log,此时redo logprepare状态,然后执行器执行操作,完成后提交事务成功,写入bin log,最后redo log更新为commit
  5. 更新完成。

参考文献

SQL语句在MySQL中的执行过程

高性能MySQL(第4版)

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

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

相关文章

别再错过!这些隐藏版小网站,让你大呼过瘾!

今天给大家分享一些摸鱼小网站&#xff0c;再忙也别忘记摸鱼呀~~~ 01、简约时钟 网址&#xff1a;https://dateclock.net/ github&#xff1a;https://github.com/jtheletter/dateclock 这个是github上的一个开源项目&#xff0c;大家可以看到它的全部代码。打开网站就能看到…

法语 Alt 代码表

法语的 Alt 代码表&#xff0c;请参考下图。 输入方法就是按住 Alt 键不松开&#xff0c;然后在小键盘上输入字符&#xff0c;松开 Al 键&#xff0c;计算机就能输出上面的字符了。 西班牙语 Alt 代码表 - 系统容器 - iSharkFly西班牙语 Alt 代码表&#xff0c;请参考下图。 输…

《大模型合规白皮书2023》:为了解大模型立法最新动态和立法趋势提供有价值的参考

本白皮书在我国人工智能法律监管框架下进一步梳理了大模型相关方的合规义务及要点&#xff0c;并展望未来大模型法律监管体系的发展趋势与特征&#xff0c;对政府、企业、社会共建大模型治理体系提出切实建议&#xff0c;从而为社会各界了解大模型立法最新动态和立法趋势提供有…

C++ Qt开发:Slider滑块条组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍Slider滑块条组件的常用方法及灵活运用。 当…

Docker容器:docker推送镜像至Harbor

目录 1、Harbor创建项目 2、进入test项目&#xff0c;查看推送命令 3、在docker服务器上准备一个镜像 4、修改docker客户端配置 5、重启docker服务 6、docker登录Harbor 7、docker镜像推送到Harbor 1、Harbor创建项目 2、进入test项目&#xff0c;查看推送命令 3、在dock…

css3实现动态心电图折线

css3实现动态心电图折线 M&#xff08;moveto&#xff09;&#xff1a;需要两个参数&#xff08;x轴和y轴坐标&#xff0c;移动到的点的x轴和y轴的坐标L&#xff08;lineto&#xff09;&#xff1a;需要两个参数&#xff08;x轴和y轴坐标&#xff09;&#xff0c;它会在当前位置…

挺进云存储,天翼云全新一代XSSD勇立潮头

引言&#xff1a;自研高性能分布式存储引擎LAVA&#xff0c;实现云硬盘持续创新获得新突。 【全球云观察 &#xff5c; 科技热点关注】 作为算力基础设施的基石&#xff0c;云存储的发展一直备受公有云厂商所重视&#xff0c;对拉动云厂商营收规模带来重要价值&#xff0c;就…

微信开发者工具安装教程

文章目录 下载安装包执行安装包 #微信开发者工具安装教程 下载安装包 官网网址 执行安装包 D:\Program Files (x86)\Tencent\微信web开发者工具\dll

联合体(c语言)

1.联合体由一个或多个成员组成&#xff0c;这些成员可以是不同类型&#xff0c;但编译器只为最大的数据成员分配足够的内存空间&#xff0c;所有成员占一个空间&#xff0c;所以联合体也叫共用体&#xff08;可以利用这一点用不同的变量表示同一快空间)&#xff0c;给其中一个成…

Git应用——代码提交规范 feat ,fix ,style

当前使用 feat 增加新功能fix 修复问题/BUGstyle 代码风格相关无影响运行结果的perf 优化/性能提升refactor 重构revert 撤销修改test 测试相关docs 文档/注释chore 依赖更新/脚手架配置修改等workflow 工作流改进ci 持续集成types 类型定义文件更改wip 开发中 别处看到 fea…

椋鸟C语言笔记#26:数据在内存中的存储(大小端字节序)、浮点数的存储(IEEE754)

萌新的学习笔记&#xff0c;写错了恳请斧正。 目录 大小端字节序 什么是大小端 写一个判断大小端的程序 浮点数在内存中的存储&#xff08;IEEE 754规则&#xff09; 引入 存储规则解释 读取规则解释 1.阶码不全为0或全为1&#xff08;规格化数&#xff09; 2.阶码全为…

IDEA Maven项目如何引用本地jar包,并打包发布

jar包位于当前路径下的lib目录中 引入所需要的配置 查看当前jar包的相关信息 包的引入,需要使用到当前包的artifactId, groupId, version 需要到包的/META-INF/maven/ 下面的 pom.xml 文件里面找 在Maven构建项目时&#xff0c;生成的依赖包中的/META-INF/maven目录存放了一些…

【JUC】二十八、synchronized锁升级之偏向锁

文章目录 1、偏向锁出现的背景2、从共享对象的内存结构看偏向锁3、偏向锁的持有4、启动偏向锁5、sleep暂停来启动偏向锁6、偏向锁的撤销7、总体流程8、SinceJava15 偏向锁的废除 1、偏向锁出现的背景 如果一个线程连续几次抢到锁&#xff0c;仍然重复加锁解锁&#xff0c;就会…

【深度学习】注意力机制(六)

本文介绍一些注意力机制的实现&#xff0c;包括MobileVITv1/MobileVITv2/DAT/CrossFormer/MOA。 【深度学习】注意力机制&#xff08;一&#xff09; 【深度学习】注意力机制&#xff08;二&#xff09; 【深度学习】注意力机制&#xff08;三&#xff09; 【深度学习】注意…

产品入门第三讲:Axure产品流程图绘制

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还…

机器人行业数据闭环实践:从对象存储到 JuiceFS

JuiceFS 社区聚集了来自各行各业的前沿科技用户。本次分享的案例来源于刻行&#xff0c;一家商用服务机器人领域科技企业。 商用服务机器人指的是我们日常生活中常见的清洁机器人、送餐机器人、仓库机器人等。刻行采用 JuiceFS 来弥补对象存储性能不足等问题。 值得一提的是&am…

Docker容器如何优雅地访问宿主机网络

# 前言 某些时候&#xff0c;我们会有在容器内容访问宿主机某个服务的需求&#xff0c;比如现在 openai 无法直接访问&#xff0c;需要给项目添加代理&#xff0c;我的 chatgpt-dingtalk (opens new window) 项目支持了通过环境变量指定代理地址。 添加方式如下&#xff1a; …

嵌入式奇妙之旅:Python与树莓派编程深度探索

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在这个数字化的时代&#xff0c;嵌入式系统的应…

主动学习与弱监督学习

人工智能数据的获取没有想象中的那么简单&#xff0c;虽然我们早已身处大数据的浪潮下&#xff0c;很多公司在获取数据的大浪中翻滚却始终没有找到一个合适的获取数据的渠道。很多情况下&#xff0c;获取高质量的人工智能数据需要消耗大量的人力、时间、金钱&#xff0c;但是对…

Vue3-08-条件渲染-v-if 的基本使用

v-if 是什么 v-if 一个指令&#xff0c; 它是用来根据条件表达式&#xff0c;进行选择性地【展示】/【不展示】html元素的。比如 &#xff1a; 有一个按钮A&#xff0c;当条件为真时&#xff0c;展示该按钮&#xff1b;条件为假时&#xff0c;不展示该按钮。与 js 中的 条件判…