文章目录
- MySQL逻辑架构整体分为三层
- 连接层
- 服务层
- 查询缓存
- 解析器
- 优化器
- 执行器
- 存储引擎层
- 系统文件层
- MySQL 查询过程
- 查询过程框图
博客1
博客2
MySQL逻辑架构整体分为三层
-
最上层为客户端层,并非MySQL所独有,诸如:连接管理、授权认证、权限校验等功能均在这一层处理。
-
MySQL大多数核心服务均在中间这一层,包括查询解析、优化、执行、缓存、内置函数(比如:时间、数学、加密等函数)。所有的跨存储引擎的功能也在这一层实现:存储过程、触发器、视图等。
-
最下层为存储引擎,其负责 MySQL 中的数据存储和提取。和 Linux 下的文件系统类似,每种存储引擎都有其优势和劣势。中间的服务层通过API与存储引擎通信,这些API接口屏蔽了不同存储引擎间的差异。
连接层
连接层主要负责连接管理、授权认证、权限校验等功能。
-
连接管理:
负责客户端与 MySQL 服务器之间的连接建立、维护和终止。客户端发起连接请求,MySQL 服务器接收到请求;每个客户端连接对应服务器上的一个线程,服务器利用线程池来管理这些连接,避免频繁创建和销毁线程,提高效率;当客户端请求断开连接时,服务器会关闭相应的线程,释放资源;
-
身份认证:
在客户端输入连接命令(如 mysql -uxxx -pxxx)后,连接层的第一步是进行身份验证。通过用户名和密码进行认证,确保只有授权用户才能访问数据库。还支持 SSL 证书认证,提供更高级别的安全性,确保数据在传输过程中不被窃取。认证成功后,服务器会加载用户的权限信息。
-
权限校验:
登录后,连接层会检查用户是否有执行特定操作的权限。这包括对数据库、表和其他资源的访问控制,确保用户只能访问其权限范围内的数据。如果权限不足,服务器会拒绝该请求,并返回相应的错误信息。
-
比如输入的 mysql -uxxx -pxxx 之后,来到MySQL的第一件事就是校验身份,权限等。每个客户端连接都对应着服务器上的一个线程。服务器上维护了一个线程池,避免为每个连接都创建销毁一个线程。当客户端连接到 MySQL 服务器时,服务器对其进行认证。可以通过用户名与密码认证,也可以通过 SSL 证书进行认证。登录认证后,服务器还会验证客户端是否有执行某个查询的操作权限。
服务层
- 认证成功过后,接下来就来到服务层了,服务层是 MySQL 的核心,MySQL 的核心服务层都在这一层,包括要执行的任何 SQL 语句,普通的 DDL、DML、DQL、存储过程、视图、触发器等都需要经过这一层的一些操作,最终才可以被 MySQL 识别。主要经过有 SQL 解析器、SQL 优化器等,最终还会经过查询缓存,总之,所有跨存储引擎的功能都在这一层实现。
查询缓存
-
在执行 SELECT 语句之前,MySQL 会检查查询缓存(Query Cache)。如果相同的 SQL 查询请求已经存在于缓存中,MySQL 会直接返回缓存中的结果,服务器就不需要再执行查询解析、优化和执行的整个过程;
-
对于相同的查询请求,可以快速返回结果,减少处理时间。但不推荐使用查询缓存,为什么呢?因为查询缓存往往弊大于利。一旦对表进行任何更新(如 INSERT、UPDATE 或 DELETE),该表上的所有查询缓存都会被清空。这导致在高更新频率的数据库中,查询缓存的命中率很低,反而会影响性能。除非业务需求中需要使用一张静态表,很长时间才会更新一次,比如系统配置表,那这张表上的查询才适合使用查询缓存。MySQL8.0 彻底废弃了查询缓存的功能,MySQL 8.0 的设计更注重高效的查询处理和优化,而不是依赖查询缓存。
-
虽然查询缓存已被废弃,但在早期版本中,开发者仍然可以通过设置 query_cache_type 参数来控制缓存行为。可以将参数 query_cache_type 设置成DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。
解析器
-
如果缓存没有命中的话,MySQL 解析器会对查询语句进行进行语法和语义分析,确保 SQL 语句符合 SQL 标准,并且逻辑上正确。解析的结果生成一个内部表示,这个表示用于后续的优化和执行。简单说解析的作用将我们人能看懂的 SQL 解析成 MySQL 能识别的语言;
-
解析器先会做 “词法解析”。词法解析是一种将输入的 SQL 语句分解为基本组成部分的过程,这些组成部分称为“词法单元”。MySQL 会识别出 SQL 语句中的关键字(如 SELECT、FROM、WHERE 等)、表名、列名等,并将其分类。也就是 MySQL 需要识别出里面的字符串分别是什么,代表什么;
-
做完“词法解析”,接着做“语法解析”。语法解析基于词法解析的结果,检查 SQL 语句的结构是否符合 MySQL 的语法规则,判断输入的这个 SQL 语句是否满足 MySQL 语法。如果语法正确,语法解析器会生成一个语法树(或解析树),这是 SQL 语句的内部表示形式,便于后续处理;
优化器
-
经过了解析器器,MySQL 知道要做什么了。接下来并不是直接执行,而是会在优化器这一层进行优化,优化器是个非常复杂的部件,它会按照它认为的最好的方式去优化这条 SQL 语句,并生成一条条的执行计划。
优化过程可能包括选择合适的索引、确定连接顺序、重写查询等,以提高查询性能:
- 索引选择:当查询涉及多个索引时,优化器会评估每个索引的使用效率,决定采用哪个索引进行查询。这包括考虑索引的选择性、数据分布等因素;
- 连接顺序优化:在执行多表关联(JOIN)时,优化器会决定表的连接顺序。不同的连接顺序可能会导致不同的查询效率,优化器会选择最优的顺序;
- 查询重写:优化器可以对 SQL 语句进行重写,以简化查询并提升性能。例如,它可能会将某些子查询转换为 JOIN,从而减少数据处理的复杂性;
例如在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的join:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
-
既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20。
-
也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。
这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。
优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。
执行器
-
MySQL 通过解析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段。执行器会根据优化器生成的执行计划,去调用执行引擎会调用相应的存储引擎接口,进行数据的读取、插入、更新和删除操作;
-
在执行 SQL 语句之前,执行器会首先检查用户对目标表的操作权限;
mysql> select * from T where ID=10; ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
-
如果有权限,就打开表继续执行。打开表的时候,执行器根据表的存储引擎定义,使用相应的存储引擎接口打开表;
-
比如上述sql查询表T语句,ID字段没有索引,执行器的执行流程处理流程:
- 调用 InnoDB 引擎接口,读取表的第一行数据,检查 ID 值是否为 10。如果 ID 值不匹配,则跳过这行;如果匹配,则将该行添加到结果集中;
- 继续调用引擎接口获取“下一行”数据,重复上述检查逻辑,直到遍历完整个表;
- 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。
-
对于有索引的表,执行的逻辑与无索引的表类似,但效率更高。
- 执行器首先调用引擎接口,获取满足条件的第一行数据,由于索引的存在,查找和定位数据的过程更为高效;
- 通过调用接口,循环获取“满足条件的下一行”,直到没有更多匹配的行。每次获取时,执行器会根据索引的顺序直接定位到相关数据,减少了不必要的全表扫描;
- 将所有满足条件的记录组成的结果集返回给客户端;
存储引擎层
-
根据优化器生成的执行计划,执行引擎负责实际的数据检索和操作。执行引擎会调用相应的存储引擎接口,进行数据的读取、插入、更新和删除操作;
-
MySQL 提供了可插拔式的存储引擎,即 “插上什么存储引擎,就有什么功能”,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 与存储引擎进行通信,不同的存储引擎具有功能不同。不同的存储引擎将直接决定了数据存储到磁盘的方式。例如,InnoDB 使用聚簇索引存储数据,而 MyISAM 使用非聚簇索引;
系统文件层
- 系统文件层是 MySQL 逻辑架构中负责数据持久化和存储的底层组件。它主要涉及数据的存储与管理,确保数据能够安全、有效地写入磁盘,并与存储引擎进行交互。
- 数据存储:负责将数据以文件的形式存储在操作系统的文件系统中;
- 与存储引擎交互:系统文件层通过 API 与存储引擎进行通信,完成数据的写入和读取操作。这一层使存储引擎能够透明地处理数据存储的细节。
MySQL 查询过程
查询过程框图
我们总是希望MySQL能够获得更高的查询性能,最好的办法是弄清楚MySQL是如何优化和执行查询的。一旦理解了这一点,就会发现:很多的查询优化工作实际上就是遵循一些原则让MySQL的优化器能够按照预想的合理方式运行而已。
当向MySQL发送一个请求的时候,MySQL到底做了些什么呢?
-
接收请求
客户端连接:客户端通过连接管理与 MySQL 服务器建立连接,并发送 SQL 查询请求。
-
查询缓存(可选)
如果启用了查询缓存,MySQL 会检查该查询是否已有缓存的结果。如果缓存中存在该查询的结果,MySQL 会直接返回缓存结果,而无需执行查询。
-
查询解析
语法解析:MySQL 的查询解析器会检查 SQL 查询的语法,确保其符合 SQL 标准。
语义分析:解析器验证表名、列名是否存在,以及用户是否有权限执行该查询。
-
查询优化
生成执行计划:查询优化器分析解析后的 SQL 语句,生成一个或多个执行计划。
优化器使用统计信息(如表的行数、索引的选择性等)来评估不同的执行计划,并选择最优的执行路径。
-
执行查询
调用存储引擎:优化后的执行计划会被传递给执行引擎,MySQL 根据计划调用相应的存储引擎执行实际的数据操作。
数据检索:存储引擎根据执行计划从磁盘读取数据,进行必要的计算和处理(如连接、排序等)。
-
返回结果
结果集返回:执行引擎将结果集通过服务层返回给客户端。
连接管理:客户端接收到结果后,可以继续发送其他查询或关闭连接。
详解一条 SQL 的执行过程