持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
前言
上篇我们学习了MySQL中的SQL执行流程。有兴趣的小伙伴可以阅读(MySQL学习-SQL执行流程(一))。
下面我们继续学习MySQL中的SQL执行流程。
SQL执行流程
上一节学习了查询缓存,下面继续学习其他流程。
解析器
SQL流程中,如果没有在查询缓存中找到对应的SQL语句,则进入到解析器流程中。在解析器中,会对SQL语句进行语法分析和语义分析。
分析器会先做词法分析。按照输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别里面的字符串分别是什么,代表什么。MySQL从输入的“SELECT”这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名T”,把字符串“ID”识别成“列ID”。如下语句:
SELECT employee_id, name
FROM employees
WHERE employee_id = 100;
接着,做语法分析。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。如果SQL语句正确,会生成一个语法树。
优化器
生成语法树后,会进入优化器,在优化器中会确定SQL语句的执行路径,如果是根据全表检索,还是根据索引检索等。
举例一
SELECT *
FROM test1
JOIN test2 using(ID)
WHERE test1.name='xiaolan' and test2.name='mysql';
- 方案一:先从test1表里面取出name='xiaolan'的记录的ID值,再根据ID值关联到test2,再判断test2里面name的值是否等于mysql。
- 方案二:先从test2表里面取出name='mysql'的记录的ID值,再根据ID值关联到test1,再判断test1里面name的值是否等于xiaolan。
这两种方案的执行结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。在查询优化器中,可以分为逻辑查询优化阶段和物理查询优化阶段。
执行器
截止到目前,还没有真正去读写真实的表,仅仅是产出了一个执行计划。于是就进入了执行器阶段。在执行之前需要判断该用户是否具备权限。如果没有,就会返回错误,如果具备权限,就执行SQL查询并返回结果。在MySQL8.0以下的版本,如果设置了查询缓存,这时会将查询结果进行缓存。
举例二
SELECT *
FROM test
WHERE id=1;
以上查询语句,执行器的执行流程是这样的:
- 调用InnoDB引擎接口取这个表的第一行,判断ID值是不是1,如果不是则跳过,如果是则将这行存在结果集中。
- 调用引擎接口取下一行,重复相同的判断逻辑,直到取到这个表的最后一行。
- 执行器将上述遍历过程中所有满足条件的的行组成的记录集作为结果返回给客户端。
至此,这个语句就执行完成了。
今天先学习到这里,明天继续。