SQL语句在MySQL中的执行过程这篇文章中的一个疑问(错误?)
fox-half-tian opened this issue · 1 comments
原文内容:
说了以上这么多,那么究竟一条 SQL 语句是如何执行的呢?其实我们的 SQL 可以分为两种,一种是查询,一种是更新(增加,修改,删除)。我们先分析下查询语句,语句如下:
select * from tb_student A where A.age='18' and A.name=' 张三 ';结合上面的说明,我们分析下这个语句的执行流程:
- 先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL8.0 版本以前,会先查询缓存,以这条 SQL 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。
这个第一步,在我的学习中,连接器所做的工作是进行连接管理、身份认证、权限获取。而不会在这里进行权限判断,而是在执行器阶段。
那么原文中的这句话是否有些问题呢?还是说我理解的有问题(我不太确认)。
如果上述我的描述是正确的,那么将整个这段执行流程改为以下会不会好理解些:
结合上面的说明,我们分析下这个语句的执行流程:
-
连接器:客户端与 MySQL 服务器建立 TCP 连接,MySQL 服务器会对传输过来的用户名和密码进行身份认证与权限获取。具体来说:
- 用户名或密码不对,会收到一个
Access denied for user
错误,客户端程序结束执行。 - 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依赖于此时读到的权限。
- 用户名或密码不对,会收到一个
-
查询缓存:如果在查询缓存中发现了这条 SQL 语句,就会直接将结果返回给客户端;如果没有,就进入到分析器阶段。需要说明的是,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃了这个功能。
-
分析器:主要分为两步,词法分析和语法分析,先看 SQL 语句要做什么,再检查 SQL 语句语法是否正确,生成语法分析树。
- 词法分析:先看这个 SQL 要做什么,提取 SQL 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id='1'。
- 语法分析:再检查 SQL 语句语法是否正确,比如关键词是否正确等等,生成语法分析树,如果检查没问题就执行下一步。
-
优化器:优化器对查询进行优化,包括重写查询、决定表的读写顺序以及选择合适的索引等,生成执行计划。上面的 SQL 语句,可以有两种执行方案:a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。
-
执行器:首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息。如果有权限,就会根据执行计划去调用存储引擎 API 对表进行的读写。