Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL语句在MySQL中的执行过程这篇文章中的一个疑问(错误?) #2466

Open
fox-half-tian opened this issue Aug 28, 2024 · 1 comment

Comments

@fox-half-tian
Copy link
Contributor

🏠 SQL语句在MySQL中的执行过程

原文内容:

说了以上这么多,那么究竟一条 SQL 语句是如何执行的呢?其实我们的 SQL 可以分为两种,一种是查询,一种是更新(增加,修改,删除)。我们先分析下查询语句,语句如下:

select * from tb_student  A where A.age='18' and A.name=' 张三 ';

结合上面的说明,我们分析下这个语句的执行流程:

  • 先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL8.0 版本以前,会先查询缓存,以这条 SQL 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。

这个第一步,在我的学习中,连接器所做的工作是进行连接管理、身份认证、权限获取。而不会在这里进行权限判断,而是在执行器阶段。

那么原文中的这句话是否有些问题呢?还是说我理解的有问题(我不太确认)。

如果上述我的描述是正确的,那么将整个这段执行流程改为以下会不会好理解些:


结合上面的说明,我们分析下这个语句的执行流程:

  1. 连接器:客户端与 MySQL 服务器建立 TCP 连接,MySQL 服务器会对传输过来的用户名和密码进行身份认证与权限获取。具体来说:

    • 用户名或密码不对,会收到一个 Access denied for user 错误,客户端程序结束执行。
    • 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依赖于此时读到的权限。
  2. 查询缓存:如果在查询缓存中发现了这条 SQL 语句,就会直接将结果返回给客户端;如果没有,就进入到分析器阶段。需要说明的是,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃了这个功能。

  3. 分析器:主要分为两步,词法分析语法分析,先看 SQL 语句要做什么,再检查 SQL 语句语法是否正确,生成语法分析树

    • 词法分析:先看这个 SQL 要做什么,提取 SQL 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id='1'。
    • 语法分析:再检查 SQL 语句语法是否正确,比如关键词是否正确等等,生成语法分析树,如果检查没问题就执行下一步。
  4. 优化器:优化器对查询进行优化,包括重写查询、决定表的读写顺序以及选择合适的索引等,生成执行计划。上面的 SQL 语句,可以有两种执行方案:a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。

  5. 执行器:首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息。如果有权限,就会根据执行计划去调用存储引擎 API 对表进行的读写。

@Renzhz
Copy link

Renzhz commented Oct 22, 2024

同问

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants