优化器
经过分析器的词法分析和语法分析后,你这条 SQL 就合法
了,MySQL 就知道你要做什么了。但是在执行前,还需要进行优化器的处理,优化器会判断你使用了哪种索引,使用了何种连接,优化器的作用就是确定效率最高的执行方案。
执行器
MySQL 通过分析器知道了你的 SQL 语句是否合法,你想要做什么操作,通过优化器知道了该怎么做效率最高,然后就进入了执行阶段,开始执行这条 SQL 语句
在执行阶段,MySQL 首先会判断你有没有执行这条语句的权限,没有权限的话,就会返回没有权限的错误。如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。对于有索引的表,执行的逻辑也差不多。
至此,MySQL 对于一条语句的执行过程也就完成了。
SQL 的执行顺序
我们在编写一个查询语句的时候
它的执行顺序你知道吗?这道题就给你一个回答。
FROM 连接
首先,对 SELECT 语句执行查询时,对FROM
关键字两边的表执行连接,会形成笛卡尔积
,这时候会产生一个虚表VT1(virtual table)
“首先先来解释一下什么是
笛卡尔积
现在我们有两个集合 A = {0,1} , B = {2,3,4}
那么,集合 A * B 得到的结果就是
A * B = {(0,2)、(1,2)、(0,3)、(1,3)、(0,4)、(1,4)};
B * A = {(2,0)、{2,1}、{3,0}、{3,1}、{4,0}、(4,1)};
上面 A * B 和 B * A 的结果就可以称为两个集合相乘的
笛卡尔积
我们可以得出结论,A 集合和 B 集合相乘,包含了集合 A 中的元素和集合 B 中元素之和,也就是 A 元素的个数 * B 元素的个数
再来解释一下什么是虚表
“在 MySQL 中,有三种类型的表
一种是
永久表
,永久表就是创建以后用来长期保存数据的表一种是
临时表
,临时表也有两类,一种是和永久表一样,只保存临时数据,但是能够长久存在的;还有一种是临时创建的,SQL 语句执行完成就会删除。一种是
虚表
,虚表其实就是视图
,数据可能会来自多张表的执行结果。
ON 过滤
然后对 FROM 连接的结果进行 ON 筛选,创建 VT2,把符合记录的条件存在 VT2 中。
JOIN 连接
第三步,如果是 OUTER JOIN(left join、right join)
,那么这一步就将添加外部行,如果是 left join 就把 ON 过滤条件的左表添加进来,如果是 right join ,就把右表添加进来,从而生成新的虚拟表 VT3。
WHERE 过滤
第四步,是执行 WHERE 过滤器,对上一步生产的虚拟表引用 WHERE 筛选,生成虚拟表 VT4。
WHERE 和 ON 的区别
- 如果有外部列,ON 针对过滤的是关联表,主表(保留表)会返回所有的列;
- 如果没有添加外部列,两者的效果是一样的;
应用
- 对主表的过滤应该使用 WHERE;
- 对于关联表,先条件查询后连接则用 ON,先连接后条件查询则用 WHERE;
GROUP BY
根据 group by 字句中的列,会对 VT4 中的记录进行分组操作,产生虚拟机表 VT5。果应用了group by,那么后面的所有步骤都只能得到的 VT5 的列或者是聚合函数(count、sum、avg等)。
HAVING
紧跟着 GROUP BY 字句后面的是 HAVING,使用 HAVING 过滤,会把符合条件的放在 VT6
SELECT
第七步才会执行 SELECT 语句,将 VT6 中的结果按照 SELECT 进行刷选,生成 VT7