MySQL 查询执行顺序?


前言

MySQL 查询执行顺序?好吧,之前都没有看到过的一个知识点

一、SQL查询执行顺序

(7)     SELECT 
(8)     DISTINCT <select_list>
(1)     FROM <left_table>
(3)     <join_type> JOIN <right_table>
(2)     ON <join_condition>
(4)     WHERE <where_condition>
(5)     GROUP BY <group_by_list>
(6)     HAVING <having_condition>
(9)     ORDER BY <order_by_condition>
(10)    LIMIT <limit_number>

二、具体步骤

执行顺序简介

在SQL语句的执行过程中,每一步都会产生一个虚拟表(Virtual Table,简称VT),用来保存SQL语句的执行结果,以下是上述SQL的执行顺序。

1、执行FROM语句

第一步,执行FROM语句。我们首先需要知道最开始从哪个表开始的,这就是FROM告诉我们的。经过FROM语句对两个表执行笛卡尔积,会得到一个虚拟表,暂且叫VT1。总共有——table1的记录条数 * table2的记录条数——条记录,这就是VT1的结果。

2、执行ON过滤

执行完笛卡尔积以后,接着就进行ON join_condition条件过滤,比如ON a.customer_id = b.customer_id,根据ON中指定的条件,去掉那些不符合条件的数据,得到VT2表。

3、添加外部行(外联结)

这一步只有在连接类型为OUTER JOIN时才发生,如LEFT OUTER JOIN(左连接)、RIGHT OUTER JOIN(右连接)和FULL OUTER JOIN(经过测试Mysql不支持该连接方式)。大多数时候会省略OUTER关键字。
添加外部行的工作就是在VT2表的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予NULL值,最后生成虚拟表VT3。
举个例子:

+-------------+----------+----------+-------------+
| customer_id | city     | order_id | customer_id |
+-------------+----------+----------+-------------+
| baidu       | hangzhou |     NULL | NULL        |
+-------------+----------+----------+-------------+

这一行数据要是在上一步ON过滤:ON a.customer_id = b.customer_id中是绝对会被过滤掉的,但是如果我们的外连接是LEFT JOIN,则需要补充这一行数据,成为我们的VT3。回顾一下左连接:

LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。

4、执行WHERE过滤

对添加外部行得到的VT3进行WHERE过滤,只有符合 where_condition 的记录才会输出到虚拟表VT4中。

5、执行GROUP BY分组

上面得到的虚拟表还没有经过聚合分组,GROU BY子句主要是对使用WHERE子句得到的虚拟表进行分组操作。得到的内容会存入虚拟表VT5中,此时,我们就得到了一个VT5虚拟表,接下来的操作都会在该表上完成。

6、执行HAVING过滤

这里需要注意的是到目前为止已经有了三种过滤,ON、WHERE和HAVING,三者在执行时间段上是有严格区别的,HAVING子句主要和GROUP BY子句配合使用,对分组得到的VT5虚拟表进行条件过滤,然后得到虚拟表VT6。

7、SELECT列表

从虚拟表VT6中选择出我们需要的内容,生成虚拟表VT7。

8、执行DISTINCT子句

如果在查询中指定了DISTINCT子句,则会创建一张内存临时表(如果内存放不下,就需要存放在硬盘了)。这张临时表的表结构和上一步产生的虚拟表VT7是一样的,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来除重复数据。

9、执行ORDER BY子句

对虚拟表中的内容按照指定的列进行排序,然后返回一个新的虚拟表,上述结果会存储在VT8中。

10、执行LIMIT子句

LIMIT子句从上一步得到的VT8虚拟表中选出从指定位置开始的指定行数据。mysql的limit语法如下:

LIMIT n,m
从第n条记录开始,选择m条数据,用于分页场景较多。但是limit的性能在数据量稍微大一点的时候就会急剧下降。

总结

明确了SQL语句的逻辑执行顺序之后,写SQL的时候思路应该会好一点

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

Destinyづ 香④

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值