前言
我们在学习一种技术的时候,首先要鸟瞰其全貌,千万不要一开始就陷入到细节中去,这样有助于我们站在高维度其理解问题 —— 丁奇。
学习MySQL也是一样,所以我们可以从一条查询语句的执行开始看起。
select * from t where id = 1;
通常情况下,我们在使用MySQL的时候,只是从客户端输入一行指令,然后获取一个返回结果。
但是对于一个开发人员来说,只知道这些是远远不够的,我们还需要知道这句指令背后的执行流程,便于排查问题。
MySQL逻辑架构
这里还是引用丁奇老师的MySQL系统结构图:
MySQL可以分为Service层和存储引擎层两部分。
- Service层又可分为:连接器、查询缓存、分析器、优化器、执行器。在MySQL中,跨存储引擎层的的功能都在这一层实现,如日期函数、存储过程、视图等。
- 存储引擎层负责数据的存储和提取,是一个插件式的结构,一个Service可以对应多个存储引擎。常见的存储引擎有:InnoDB、MyISAM、Memory等。
连接器
连接器负责客户端与Mysql服务器的建立连接、获取权限、管理连接。连接命令一般是这么写的:
mysql -h$ip -P$port -u$user -p
如果用户名和密码校验通过后,连接器就会从权限表中查到该用户的权限。后续当该用户执行操作的时候,依赖的都是这个时候读取到的权限。
创建连接后,我们就可以使用 show processlist查看该连接:
如果客户端在一段时间没用任何指令,那么这个连接就会被断开。这个参数是wait_timeout,默认时间为8小时。
这里还涉及到一个概念, 长连接和短连接 。
- 长连接:建立连接后,如果客户端持续有请求,则一直使用同一个连接。
- 短连接:指执行完很少的指令,连接就断开了,如果有后续的指令,就需要重新建立连接。
建立连接的过程是相对复杂的,所以我们应该避免短连接,那是不是连接越长越好?也不是这样。MySQL在执行过程中使用的内存是管理在连接中的,这些资源资源会在断开连接的时候才会被释放。如果一直得不到释放,就会有OOM的问题,表现出来的现象就是MySQL异常重启了。
- 所以我们需要定时的断开长连接,或者是判断执行过一个占用内存的大查询后,断开连接。
- 如果是Mysql 5.7版本后,可以在执行一个大操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。
查询缓存
通常情况下我们不会启用查询缓存,因为这个缓存命中率不高,每次对表的更新,都会清空缓存。在MySQL8.0后的版本被移除。
分析器
MySQL中的分析器,主要有两个作用,分别是词法分析和语法分析。词法分析的作用是将SQL语句将我们的数据库结构相对应,比如将字符t对应成表T,将字符id对应表中的id列。
select * from t where id = 1;
语法分析做的是检测我们输入的命令是否符合MySQL语法,如果语句不对,则会有相应的提示,便于我们去修改:
优化器
经过了分析器,MySQL已经知道了我们想做什么了,接下来就该是怎么做。
比如在有多个索引的时候,选择哪个索引可以减少扫描数据的行数。进行多表联合查询的时候,哪张表作为驱动表,会减少扫描数据的行数等。
执行器
执行器的工作就是执行语句,但是在执行之前,会先判断该用户的权限,只有通过了权限认证,才可以执行语句。如果该用户有权限,执行器会打开表,调用相应存储引擎的接口,而存储引擎接口负责将数据存入结果集中返回给客户端。
小结
以上就是一条查询语句在MySQL中的执行过程,这对我们理解MySQL的执行过程,进行数据库调优是十分重要的。