第一步:连接器
要使用 MySQL,第一步肯定是要先连接 MySQL 服务,然后才能执行 SQL 语句
连接的过程需要先经过 TCP 三次握手,因为 MySQL 是基于 TCP 协议进行传输的
如果 MySQL 服务正常运行,完成 TCP 连接的建立后,连接器就要开始验证你的用户名和密码
如果用户名或密码不对,就收到一个"Access denied for user"的错误,然后客户端程序结束执行。
如果用户密码都没有问题,连接器就会获取该用户的权限,然后保存起来,后续该用户在此连接里的任何操作,都会基于连接开始时读到的权限进行权限逻辑的判断。
所以,如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。
第二步:查询缓存
连接器得工作完成后,客户端就可以向 MySQL 服务发送 SQL 语句了,MySQL 服务收到 SQL 语句后,就会解析出 SQL 语句的第一个字段,看看是什么类型的语句。
如果 SQL 是查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句,value 为 SQL 语句查询的结果。
如果查询的语句命中查询缓存,那么就会直接返回 value 给客户端。如果查询的语句没有命中查询缓存中,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。
对于更新比较频繁的表,查询缓存的命中率很低的,因为只要一个表有更新操作,那么这个表的查询缓存就会被清空。
所以,MySQL 8.0 版本直接将查询缓存删掉了,也就是说 MySQL 8.0 开始,执行一条 SQL 查询语句,不会再走到查询缓存这个阶段了。
第三步:解析 SQL
解析器会做词法分析和句法分析,负责检查语法和构建语法树
如果我们输入的 SQL 语句语法不对,就会在解析器这个阶段报错。
第四步:执行 SQL
每条SELECT
查询语句流程主要可以分为下面这三个阶段:
- prepare 阶段,也就是预处理阶段;
- optimize 阶段,也就是优化阶段;
- execute 阶段,也就是执行阶段;
预处理阶段:
- 检查 SQL 查询语句中的表或者字段是否存在;
- 将
select *
中的*
符号,扩展为表上的所有列;
优化阶段:
优化器主要负责将 SQL 查询语句的执行方案确定下来,比如在表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引。提高执行的效率
执行阶段:
根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端;