MySQL基本架构与查询语句执行过程
1.1概述
大体来说,MySQL可以分为Server层
和存储引擎层
两部分
- Server层包括
连接器
、查询缓存
、分析器
、优化器
、执行器
, 覆盖了MySQL的大多数核心功能,包括所有的内置函数,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等,此外还包括MySQL非常重要的二进制日志binlog。 - 而存储引擎层
负责数据的存储与提取
,其架构模式是可插拔的,支持InnoDB、MyISAM、Memory等多个存储引擎,其中最常用的就是InnoDB,也是MySQL默认使用的存储引擎。
从下图中不难看出, 不同的存储引擎共用一个Server层
, 也就是从连接器到执行器的部分。
1.2架构示意图
1.3Server层
1.3.1连接器
第一步你先要连接到MySQL数据库上,这时候工作的就是MySQL的连接器
连接器负责跟客户端建立连接
、获取权限(验证账号和密码等)
、维持和管理连接
。
连接命令一般是这样写的:
mysql -h$ip -P$port -u$user -p
连接命令中的mysql是客户端工具,用来跟服务器建立连接,在完成经典的TCP三次握手后
,连接器就开始要验证你的身份,这个时候用的就是你输入的用户名和密码
。
1.3.2查询缓存
连接建立完毕后,就可以执行select语句了,此时来到第二步:查询缓存
。
MySQL拿到一个查询请求时,首先去查询缓存中查询是否存在以查询语句为Key的对象,存在的话直接拿到Value(就是查询结果)
返回,不存在的话继续向后执行查询数据库, 查库完毕后会向缓存中存一个K—V键值对。可以减轻数据的库访问压力。
在MySQL8.0中,查询缓存已经被移除了,并且在之前存在的版本中也不建议使用查询缓存,虽然可以有效的减轻数据库的访问压力,但是只要有对一个表的删除或者修改操作,那么这个表中的所有查询缓存全部都会被情况,即查询缓存失效是非常频繁的。有可能搞了一堆缓存,结果还没用到呢一个更新操作就全没了,总体来说弊大于利。
1.3.3分析器
如果没有命中缓存,就要真正的开始执行语句了,首先MySQL得需要知道你要干什么,因此需要分析器去解析SQL语句
- 分析器先做
词法分析
分析器通过SQL语句分析出select关键字,表示是一个查询操作,然后分析出表名、列名、以及字符串等内容。 - 然后做
语法分析
语法分析就是根据词法分析的结果,分析一下这条SQL语句是否符合MySQL的语法是否有语法错误等
。如果有语法错误会报错。
1.3.4优化器
经过分析器,MySQL就知道本条是一条合法的SQL语句,并且也知道SQL语句要干什么事,在执行之前还需要经过优化器的处理
优化器是在表里面有多个索引的时候,决定使用哪个索引,以及根据联合索引的顺序优化查询的字段顺序、或者在一个语句有多表关联时(join)决定各个表的连接顺序。
优化器阶段完成后,这条SQL语句的执行方案就确定下来了,然后就进入执行器阶段。
1.3.5执行器
MySQL通过分析器知道了SQL要做什么,通过优化器知道SQL该怎么做,于是就进入了执行器开始真正的执行
首先会判断当前用户对于当前表是否有执行查询的权限,没有的话就返回没有权限的错误,有权限就打开表继续执行,打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
举例
比如我们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:
# 假设SQL语句是这条。
select * from T where ID = 10;
- 调用InnoDB引擎接口取这个表的第一行, 判断ID值是不是10, 如果不是则跳过, 如果是则将这行存在结果集中;
- 调用引擎接口取“下一行”, 重复相同的判断逻辑, 直到取到这个表的最后一行。
- 执行器将上述遍历过程中所有满足条件的行组成的记录集作为
结果集
返回给客户端。
至此, 这个语句就执行完成了
对于有索引的表, 执行的逻辑也差不多。 第一次调用的是“取满足条件的第一行”这个接口, 之后循环取“满足条件的下一行”这个接口, 这些接口都是引擎中已经定义好的。
1.4执行流程总结
- 首先与MySQL服务器建立连接
(TCP连接)
,包括验证用户名和密码等。 - 然后去查询缓存中找,找到直接返回,找不到就继续进行
(查询后放一份到缓存中)
- 分析器经过
词法分析
分析出关键字 (select/表名/列名/字符串等) 并分析出SQL要干什么,然后语法分析
检查出SQL语句是否符合语法规则。 - 优化器对如何执行SQL进行优化,包括选择合适的索引,如何连接表等。
- 执行器通过引擎真正的执行SQL语句,然后生成结果集返回。