认识MySQL查询语句的执行顺序

顺序说明

首先知道:在SQL中,子语句执行的顺序并不取决于它在整个SQL语句中所占据的位置的。执行的顺序是基于SQL规定的顺序来执行的。

接下来我们来具体解释下SQL规定的顺序是怎样的。

对于每个子句,都可以被划分到不同的执行模块中。这些执行模块分别为:得到基表,对基表进行分组,对分组表进行过滤,读取最终分组表的列。

上述所说的这些模块,它们在整个SQL语句中的执行顺序,且其与子句的对应关系,分别为:

  1. 得到基表 -> [from、join、where]
  2. 对基表进行分组 -> [group by]
  3. 对分组表进行过滤 -> [having]
  4. 读取最终分组表的列 -> [select]

在基于这4个执行模块中延伸出了一些子模块,它们是用来增强这些父模块的执行的:

  1. [聚合函数,ON] -> [having],
  2. [聚合函数,distinct,order by,limit] -> [select]

现在具体说明下这些子模块的执行顺序。

对于子模块[聚合函数,ON],聚合函数发生在ON之前。因为列需要先被计算处理,ON语句就能够基于已经被计算过了的列执行判断操作。当ON执行完了之后,才会触发HAVING,执行对行过滤的操作。

而对于子模块[聚合函数,distinct,order by,limit],其中聚合函数发生在select之前。当列被计算完成,select就能够直接读取已经被计算过了的列了,然后在此基础上,接着执行发生在select之后的[distinct,order by,limit]。[distinct,order by,limit]的执行顺序分别为,distinct -> order by -> limit。

这些模块的执行顺序如下图所示:

在这里插入图片描述

现在总结一下语句的执行顺序:

在这里插入图片描述

示例

举个例子说明下,假设有一种表名为order,结构如下:

在这里插入图片描述

需求是得到每个订单中总购买金额最高的商品。则SQL语句为:

select 
    order.order_id,
    order.product_name,
    sum(price * product_count) AS total_amount
from order
group by order.order_id 
having on max(price * product_count) = sum(price * product_count)

这个SQL语句执行的顺序,则就是:

from -> group by -> [max,sum] -> on -> having -> sum -> select

每一个子语句的执行结果,也就是虚拟表,都会作为下一个子语句的操作表。就像是一个流一样,每个对象处理所生成的结果都会交由给下一个对象接着做处理,直到结束。

总结

  1. 在SQL中,子语句执行的顺序并不取决于它在整个SQL语句中所占据的位置。执行的顺序是基于SQL中规定的顺序来执行的。
  2. 每个阶段的SQL语句所生成的结果,在SQL的底层都会被存放进虚拟表中。这张表存放的都是来自上游语句所生成的结果,它对于我们来说是不可见的,只有当整个SQL语句都执行完毕后,最后的这个结果对我们才是可见的。
  3. SQL语句的执行,就像是一个流一样,每个子语句生成的结果都会流向下一个子语句中被处理,所以子语句都是基于上游SQL语句所生成结果进行操作的。
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值