MYSQL: 一条查询语句的执行过程是如何?
看下面一个简单的查询语句,你能想到什么?
select * from test where id = 5
我们看到的只是输入一条sql语句,然后返回一个结果,却不知道这条语句在 MySQL 内部的执行过程是怎么样的。
先看一下MYSQL的基本架构示意图:
从图中可以看出,查询语句可以分为如下部分:
1.客户端和服务器端之间的通信方式
2.查询缓存
3.查询优化处理
4.查询执行引擎
5.返回结果给客户端
MySQL 大致组成可以分为 Server 层和存储引擎层两部分。
Server层:包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层:负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。
连接器
首先,当向数据库发送连接的时候,这时候接待你的就是连接器。连接器负责跟客户端建立连接、获取权限、维持和管理连接。
连接命令一般是这么写的:
mysql -h$ip -P$port -u$user -p
查询缓存
MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接返回给客户端。如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。
需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。
分析器
分析器先会做“词法分析”。对你输入字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。以及有没有语法错误分析。
优化器
优化器是在表里面有多个索引的时候,决定使用哪个索引;
或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
执行器
1.先判断连接用户对表是否有执行查询的权限
2.有权限,则开始执行
3.没有,就会返回没有权限的结果
如下面的语句:
select * from test where id = 5
调用 InnoDB 引擎接口取这个表的第一行,判断 id 值是不是5,如果不是则跳过,如果是则将这行存在结果集中。
调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。