MySQL - 一条SQL在MySQL中是如何被执行的?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL - 一条SQL在MySQL中是如何被执行的?

1. 前言

MySQL 中针对表的操作可以分为增、删、改、查四种操作,也就是我们所说的 CRUD 大法,根据类型分为DML(增删改)和DQL(查),不管是 DML 和 DQL 都要经过连接器、查询缓存、分析器、优化器、执行器调用存储引擎的API执行最优路径。前四个阶段流程都是一样的,接下来我们一起学习执行器在存储引擎上是如何进行查询和更新(增删改查)的。

PS:查询缓存在 MySQL5.7.20 版本已过时,在 MySQL8.0 版本中被移除,这里不再单独介绍查询缓存这一流程;连接器、查询缓存、分析器、优化器、执行器的具体作用见:一文了解MySQL的基础架构及各个组件的作用。

2. MySQL是如何执行查询语句的?

如下SQL:实现查询名字为 “javaBoy001” 和年龄为 18 的用户

select id, name, sex, age from user where name = 'javaBoy001' and age = 18;

2.1 连接器

先检查该语句是否有权限,如果没有权限,直接返回错误信息。

2.2 分析器

分析器会通过词法分析,提取 SQL 语句的关键字,比如提取上面 SQL 语句的 “select”、“from”、"where"等,并可以知道这是一条查询语句,提取查询的表名为 user,提取查询的条件为 name = ‘javaBoy001’ and age = 18。

然后根据词法分析的结果,语法分析器会根据语法规则,判断你输入的SQL语句是否满足MySQL语法,没问题的执行下一步。

2.3 优化器

MySQL判断出了一条SQL语句要做什么之后,对其进行各种优化,包括重写查询语句、选择合适的索引、表的读取顺序等确定执行方案。上面的 SQL 语句存在两种执行方案:

方案1. 先查询名字为javaBoy001的所有用户,再查询年龄为18的用户;

方案2. 先查询年龄为18的用户,再查询名字为javaBoy001的所有用户;

因此,优化器需根据自己的优化算法选择自己认为执行效率最高的一个方案(优化器认为不一定是最好)。

2.4 执行器

语句经过优化后,就要进入执行阶段,开始执行的时候,要先判断权限,如果没有,就返回没有权限的错误。如果有权限,就调用存储引擎的API,返回查询结果。

3. MySQL是如何执行更新语句的?

如下SQL:实现更新名字为 “javaBoy001” 和年龄为 18 用户的手机号为 “15211111111”

update user set phone = '15211111111' where name = 'javaBoy001' and age = 18;

3.1 连接器

先检查该语句是否有权限,如果没有权限,直接返回错误信息。

3.2 分析器

分析器会通过词法分析和语法分析知道这是一条更新语句。

3.3 优化器

MySQL判断出了一条SQL语句要做什么之后,对其进行各种优化,选择合适的索引等。

3.4 执行器

语句经过优化后,就要进入执行阶段,开始执行的时候,要先判断权限,如果没有,就返回没有权限的错误。如果有权限,就调用存储引擎的API操作数据。

3.5 存储引擎更新数据

  1. InnoDB 存储引擎有一个缓冲池(Buffer Pool),查询时缓冲池里有数据就不去读取磁盘,没有就会把数据直接从磁盘里加载到缓冲池(Buffer Pool),同时加独占锁
  2. 写入数据的旧值(原有的值)到 undo_log,实现事务的原子性,提供回滚操作。
  3. 更新 Buffer Pool 中的缓存数据为新数据,此时这个新值为脏数据,因为磁盘为旧值。
  4. 为了防止 MySQL 服务器宕机,Buffer Pool 内存中的数据丢失,把 Buffer Pool 更新新值的操作写入 Redo log Buffer,这时的 redo_log 还仅仅停留在内存缓冲里。

如果还没提交事务,如果 MySQL 宕机,必然会导致 Buffer Pool 中的数据丢失,同时写入 Redo Log Buffer 中的redo_log 也会丢失。

而此时丢失的数据其实无关紧要,因为事务没有提交,则代表此次更新操作没有成功,MySQL 宕机导致内存里的数据丢失,但磁盘上的数据还是原来的值,重启 MySQL 后,数据并没有改变。

  1. 如果想要提交一个事务,此时就会根据一定的策略把 redo_log 从 redo log buffer 里刷入到磁盘,这个策略是根据 innodb_flush_log_at_trx_commit 来配置的:

(1)值为0:提交事务时,不会把 redo log buffer 里的数据刷入磁盘,MySQL 宕机,内存中的数据和 redo_log 都会丢失。

(2)值为1:提交事务时,一定会把 redo log buffer 从内存刷入到磁盘,MySQL 宕机,可以通过 redo_log 进行数据恢复。

(3)值为2:提交事务时,把 redo_log 写入磁盘文件对应的 os cache 缓存里,每隔1秒后才会把 os cache 里的数据写入到磁盘文件里。MySQL 宕机,会丢失 1s 内的更新数据。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
SQL 存储 关系型数据库
MySQL原理简介—1.SQL的执行流程
本文介绍了MySQL驱动、数据库连接池及SQL执行流程的关键组件和作用。主要内容包括:MySQL驱动用于建立Java系统与数据库的网络连接;数据库连接池提高多线程并发访问效率;MySQL中的连接池维护多个数据库连接并进行权限验证;网络连接由线程处理,监听请求并读取数据;SQL接口负责执行SQL语句;查询解析器将SQL语句解析为可执行逻辑;查询优化器选择最优查询路径;存储引擎接口负责实际的数据操作;执行器根据优化后的执行计划调用存储引擎接口完成SQL语句的执行。整个流程确保了高效、安全地处理SQL请求。
105 75
|
2天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
|
2月前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
2月前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
2月前
|
SQL 关系型数据库 MySQL
MySQL 高级(进阶) SQL 语句
MySQL 提供了丰富的高级 SQL 语句功能,能够处理复杂的数据查询和管理需求。通过掌握窗口函数、子查询、联合查询、复杂连接操作和事务处理等高级技术,能够大幅提升数据库操作的效率和灵活性。在实际应用中,合理使用这些高级功能,可以更高效地管理和查询数据,满足多样化的业务需求。
258 3
|
2月前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
2月前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。
|
15天前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
1天前
|
关系型数据库 MySQL 数据库
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
61 42
|
19天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
152 0