详解MySQL中一条SQL执行过程

news2024/9/20 0:55:32

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.coloradmin.cn/o/1308716.html

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

相关文章

QDialog子类的使用

背景&#xff1a; 我用Qt designer实现了如下效果&#xff1a; 但在实际使用的时候&#xff0c;发现OK和Cancel按钮点是点不动的。 解决方法&#xff1a; 需要手动添加相关信号槽函数&#xff1a; connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(accept()));connect…

QT多项目管理

.pro文件配置解释&#xff1a;​​​​​​ Qt 中的多项目管理_qt子目录项目-CSDN博客Qt 模块化开发之 pro 子项目开发_qt 子项目-CSDN博客关于Qt编译库&#xff08;1&#xff09;&#xff1a;在子项目中编译动态库并且使用_qt编译动态库后配置qt-CSDN博客QT release下的编译…

批量生成标题文章:AI文章创作助力高效办公,提升办公效率

随着人工智能技术的不断发展&#xff0c;AI文章创作已经成为了高效办公的新趋势。这种技术可以快速生成高质量的文章&#xff0c;从而大大提高办公效率。相比传统的手写文章&#xff0c;AI文章创作具有更高的效率和准确性。在撰写文章时&#xff0c;往往要花费大量的时间和精力…

stm32学习:hal库usart+esp8266+tcp+onenet+可以远程监督家里情况

目录 准备材料 步骤 stm32f103c8t6 在stm32clube里创建项目 先配置调试接口SYS&#xff08;博主用的是stlink&#xff0c;选的是SW&#xff09;&#xff0c;配置外部时钟源RCC&#xff0c;总线时钟频数72 配置串口&#xff08;波特率为115200&#xff09; ​编辑 看各自…

input 获取焦点后样式的修改

一、实现目标 1.没有获取焦点时样子 2.获取焦点时 代码&#xff1a; <input class"input"placeholder"请输入关键字" input"loadNode" />css .input {border-radius: 14px;border:1px solid #e4e4e4;margin: 5px;margin-top: 10px;wi…

编程应用实际场景:台球厅怎么样用电脑给客人计时,台球计时收费系统操作教程

一、前言 准确控制顾客在店内游玩的时间&#xff0c;从而控制店内的各项成本&#xff0c;并提升店内的客流量。在顾客享受计时项目的时候&#xff0c;可以同时添加其他食物消费&#xff0c;并将单据合并统一结账。软件中的会员功能可以为客户办理会员可以使用灯控器控灯&#…

【LeetCode刷题笔记(1)】【Python】【两数之和】【简单】

LeetCode: 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;找出数组中和为目标值 target 的两个整数&#xff0c;并返回它们的数组下标。 输入&#xff1a;一个整数数组 nums 和一个整数目标值 target输出&#xff1a;返回一个包含两个整数下…

【大数据】详解 AVRO 格式

详解 AVRO 格式 1.Avro 介绍2.schema2.1 原始类型2.2 复杂类型2.2.1 Records2.2.2 Enums2.2.3 Arrays2.2.4 Maps2.2.5 Unions2.2.6 Fixed 3.Avro 的文件存储格式3.1 数据编码3.1.1 原始类型3.1.2 复杂类型 3.2 存储格式3.3 存储格式 4.小结 1.Avro 介绍 Apache Avro 是 Hadoop…

阿里云SMC迁移RedHat/CentOS 5 内核升级

阿里云SMC迁移RedHat/CentOS 5 内核升级 1. 起因 服务器需要迁移上阿里云,有几台服务器用的是Redhat 5.x,在使用SMC进行迁移时出现以下报错. [2023-12-13 09:50:55] [Error] Check System Info Failed, codeS16_111, msgGet OS Info Failed: [error] grub is too old for C…

Python——数据库操作

目录 &#xff08;1&#xff09;安装Flask-SQLAlchemy &#xff08;2&#xff09;使用Flask-SQLAlchemy操作数据库 &#xff08;3&#xff09;连接数据库 •创建数据表 •增加数据 •查询数据 •更新数据 •删除数据 Flask-SQLAlchemy是Flask中用于操作关系型数据库的扩展…

Linux中使用podman管理容器

本章主要介绍使用podman管理容器 了解什么是容器&#xff0c;容器和镜像的关系安装和配置podman拉取和删除镜像给镜像打标签导出和导入镜像创建和删除镜像数据卷的使用管理容器的命令使用普通用户管理容器 对于初学者来说&#xff0c;不太容易理解什么是容器&#xff0c;这里…

【Azure 架构师学习笔记】- Azure Databricks (3) - 再次认识DataBricks

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (2) -集群 前言 在对Databricks有了初步了解之后&#xff0c;如果要深入使用则需要对其进行更深层次的了解。 Databricks ADB 是一个统一的…

C# Winfrm 编写一个天气查看助手

#前言# 最近这个北方的天气啊经常下雪&#xff0c;让我想起来我上学时候写的那个天气预报小功能了&#xff0c;今天又复现了一下&#xff0c;哈哈哈&#xff0c;大家当个乐子看哈&#xff01; 1.创建项目 2.添加引用 上图所示&#xff0c;下载所需天气预报标识&#xff0c;网站…

服务器漏洞防护措施有哪些?

随着互联网的普及和发展&#xff0c;服务器在各个领域的应用越来越广泛&#xff0c;同时也面临着越来越多的安全威胁。服务器漏洞一旦被攻击者利用&#xff0c;不仅可能导致数据泄露、系统崩溃等严重后果&#xff0c;还可能影响到企业的正常运营和声誉。因此&#xff0c;加强服…

jmeter简单压测kafka

前言 这也是一个笔记&#xff0c;就是计划用jmeter做性能测试&#xff0c;但是这里是只要将数据放到kafka的topic里&#xff0c;后面查看下游业务处理能力。 一、方案 因为只要实现数据放到kafka&#xff0c;参考了下博友的方案&#xff0c;可行。 二、方案验证 详细过程就不…

DevExpress WinForms Pivot Grid组件,一个类似Excel的数据透视表控件(二)

界面控件DevExpress WinForms的Pivot Grid组件是一个类似Excel的数据透视表控件&#xff0c;用于多维(OLAP)数据分析和跨选项卡报表。在上文中&#xff08;点击这里回顾>>&#xff09;我们介绍了DevExpress WinForms Pivot Grid组件的性能、分析服务、数据塑造能力等&…

23种策略模式之策略模式

23种策略模式之策略模式 文章目录 23种策略模式之策略模式前言优缺点使用场景角色定义UML模拟示例小结 前言 在软件开发中&#xff0c;设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式&#xff08;Strategy Pattern&#xff09;是其中一种常见的设计模式&a…

Mac配置环境变量不生效

Mac配置环境变量不生效 Mac中的环境变量介绍 Mac系统的环境变量&#xff0c;加载顺序为&#xff1a; /etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc 当然/etc/profile和/etc/paths是系统级别的&#xff0c;系统启动就会加载&#xff0c;后面…

Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯

目录 一、字符设备驱动程序框架 编写驱动程序的步骤&#xff1a; 对于 LED 驱动&#xff0c;我们想要什么样的接口&#xff1f; LED 驱动能支持多个板子的基础&#xff1a;分层思想 二、Linux驱动如何指向一个GPIO 直接通过寄存器来操作GPIO 利用引脚号操作GPIO IMX6UL…

基于自动化脚本批量上传依赖到nexus内网私服

前言 因为某些原因某些企业希望私服是不能连接外网的&#xff0c;所以需要某些开源依赖需要我们手动导入到nexus中&#xff0c;尽管nexus为我们提供了web页面。但是一个个手动导入显然是一个庞大的工程。 对此我们就不妨基于脚本的方式实现这一过程。 预期效果 笔者本地仓库…