1. 逻辑架构组成
\上方是 MySQL 逻辑架构的简单示意图,总的来说,MySQL 包含 Server 层和存储引擎层两大部分。
Server 层包括连接池、查询缓存、解析器、优化器、执行器等,MySQL 的核心服务都在这一层。
存储引擎层负责数据的存储和提取,MySQL 采用插件式的存储引擎,常见的存储引擎有 InnoDB、MyISAM、 CSV 等。其中 InnoDB 是最常用的存储引擎,也是 MySQL 的默认存储引擎(从5.5.5版本开始)。
2. 一条查询语句是如何执行的
上一小节介绍了 MySQL 的逻辑架构组成,那么各模块之间是如何协同工作的呢?这里以一条最简单的查询语句为例子,我们一起来看看这条语句在 MySQL 内部是如何执行的。
- 1
2.1 连接池
首先,我们通过 mysql 这个客户端工具进行数据库的连接,这时遇到的是连接池。连接池负责客户端的连接管理、授权认证。
连接命令如下(输入完连接命令后,需要输入用户密码):
- 1
如果用户名和密码认证通过,连接池会通过权限表获取这个用户名所拥有的权限信息;
如果用户名或密码认证不通过,则会收到一个错误提示:“ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’”;
建立连接后,会产生相应的连接信息,可以通过 show processlist 命令查看。下方图中 Id 为 5048 这一行,即为成功连接数据库所建立的连接信息,请注意 Command 这一列,值为”Sleep“,表明这是一个空闲连接。成功连接数据库后,如果没有任何动作,这个连接就会变成空闲状态。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.2 查询缓存
连接成功建立后,来到第二步查询缓存。查询缓存负责将执行过的语句和结果缓存在内存中。
在获取一个查询请求后,MySQL会先到查询缓存进行查看
- 如果select语句在查询缓存中能够找到,则直接返回结果给客户端,跳过解析、优化、执行阶段。
- 如果select语句没能在查询缓存中找到,则继续后面的解析、优化、执行阶段。
从这里可以看到,如果命中查询缓存,MySQL 会直接返回结果给客户端,后面的一系列操作不需要再执行,是非常高效的。但实际情况并非如此,查询缓存非常容易失效。
因为只要一个表有更新操作,那这个表所有的查询缓存都会被清空。对一个承载正常业务的数据库来说,更新操作是非常频繁的,这就意味着查询缓存经常失效,从而导致查询缓存的命中率非常低。所以,使用查询缓存反而会给数据库带来额外的负担,在实际生产环境中,我们建议关闭查询缓存。
关闭查询缓存的方法有两种:
临时:在 MySQL 中直接用命令行执行;
- 1
- 2
永久:将以下两个参数添加至配置文件 my.cnf,并重启 MySQL;
- 1
- 2
2.3 解析器
如果没有命中查询缓存,接下来就要进入解析器阶段了。解析器负责词法解析和语法解析。
首先是词法解析,MySQL 需要识别所输入的字符串分别代表什么,它会从左到右一个字符、一个字符地输入,然后根据构词规则识别单词。
- 1
接下来是语法解析,判断输入的这个SQL语句是否符合MySQL语法规则。如果语法不对,会收到错误信息提示:“ERROR 1064 (42000): You have an error in your SQL syntax;”。如下面这个SQL语句的where少了一个e。
- 1
- 2
2.4 优化器
从解析器出来,就到了优化器阶段。优化器负责找到最优的执行计划,也就是决定SQL语句的执行方案。
一条查询可以有很多种执行方式,最后都返回相同的结果 。比如下面这个查询SQL,查询表a中字段id等于1的值
- 1
- 可以遍历表a所有行,找出所有id等于1的值
- 也可以通过索引idx_id,找到id等于1的值。当然,前提是字段id有创建索引idx_id。
两种方案的结果是一样的,但是执行效率不一样,优化器的作用就是选择最优的执行方案。
2.5 执行器
现在到了执行SQL语句的阶段,也就是执行器。执行器负责调用存储引擎,拿到查询结果。
- 1
- 2
假设这个例子中的字段id没有索引,执行器的流程大致如下:
- 调用 InnoDB 引擎接口获取表 a 的第一行,如果 id 值等于 1,则将 id 值存进结果集,如果 id 值不等于 1,则跳过,取下一行;
- 调用 InnoDB 引擎接口获取下一行,重复第一步的逻辑,一直到表 a 的最后一行;
- 将符合查询条件的结果集返回给客户端。
3. 小结
一条 SQL 查询的过程,大致就是这样的流程:连接池、查询缓存、解析器、优化器、执行器。
连接池负责连接管理,查询缓存建议关闭,解析器让 MySQL 知道要做什么,优化器让 MySQL 知道怎么做,执行器负责执行取数。
通过本文的讲解,对您认识 MySQL 逻辑架构,有所帮助吗?欢迎反馈宝贵意见,以便我们不断改进。