准备工作
首先我们建一张test
表,里面有id
、k
、v
这三个字段,添加三条测试数据。
id | k | v |
---|---|---|
1 | k1 | v1 |
2 | k2 | v2 |
3 | k3 | v3 |
我们写一个最简单的sql:
SELECT
*
FROM
test
WHERE
id = 1
那么在mysql的架构中,这条sql是怎么执行的呢?
Mysql逻辑架构
废话不多说,我们直接上图:
![](https://xp329486175.github.io/images/blog/2019-06/mysql_01.png)
上面是一个mysql基本逻辑架构示意图。我们可以清楚的看到sql在mysql各个功能模块的执行过程。
要想执行一条查询sql。首先要经过连接器,将mysql客户端与server进行连接。然后查询缓存是否有对应信息,有就直接返回给客户端。再经过分析器, 分析词法和语法。然后由于sql的多样性,需要经过优化器,选择一个最优方式查找。然后再经过执行器,调用存储引擎执行语句。
大体来说,mysql可以分为server层
和存储引擎层
两个部分。
server层
包括连接器、查询缓存、分析器、优化器、执行器等,涵盖了mysql大多数核心服务功能,以及所有内置函数(比如时间、日期等), 所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层
负责数据的存储和提取。其架构是插件式的,常见的有InnoDB、MyISAM、Memory等存储引擎。 之前默认存储引擎是MyISAM,5.5.5版本开始将InnoDB置为默认存储引擎
。
连接器
要执行sql,第一步,我们当然是要连接到数据库。这时候接待你的就是连接器。连接器负责跟客户端建立连接、获取权限、维持和管理连接。 对应的命令就是:
mysql -h$ip -P$port -u$user -p
连接成功后,可以用show processlist
名令看到它。
查询缓存
顾名思义,就是查询之前是否已经有了缓存。但是由于表通常是有着更新删除等操作,所以查询缓存在实际意义上用处并不大。 甚至在mysql8.0直接移除这块功能了。
分析器
如果没有命中缓存,那么就需要开始真正执行语句了。首先,mysql需要知道你要做什么,因此需要对sql语句做解析。
分析器先会做词法分析
。mysql需要识别sql这里面的字符串分别代表是什么,代表什么。例如:’selest’代表查询,’test’代表表名。
做完词法分析,还需要做语法分析
,语法分析器会根据语法规则判断你你输入的这个sql是否满足语法规则。
优化器
经过了分析器,mysql就知道你要做什么了。但在开始执行之前,还需要经过优化器
的处理。优化器是判断出sql执行的最优执行方案。如:索引。
执行器
mysql通过分析器知道了要做什么,通过了优化器知道了该怎么做。于是就进入执行器阶段,开始执行语句。
开始执行的时候,会先判断你有没有相应权限。如果有权限就会打开表继续执行。打开表的时候,执行器会根据这个表定义的引擎,去使用引擎提供的接口。
比如我们上面的例子:
1、调用InnoDB引擎接口取这个表的第一行,判断id值是不是1,如果不是跳过。如果是则将这行存在结果集中。
2、调用引擎接口取"下一行",重复相同的判读逻辑,直到渠道这个表的最后一行。(条件唯一不需要执行此步骤)
3、执行器将上述过程中所有满足条件的行组成的记录集,作为结果集返回给客户端。
至此,这个sql语句就执行完成了。