MySQL中SQL的执行顺序详解

 更新时间:2025年05月13日 16:32:36   作者:duck不必鸭鸭  
这篇文章主要介绍了MySQL中SQL的执行顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

MySQL中SQL的执行顺序

在日常的开发工作中,我们经常会自己手写一些sql语句,但是对于这些sql语句是怎么执行的,执行的顺序又是怎么样的呢?想必各位大佬对此也是了解的,所以对sql语言的执行顺序有一定的了解的话,会更好的理解一些sql语句,从而更好的写sql语句,也有助于SQL的调优。就比如说,先使用子查询对数据进行过滤后在进行join操作还是直接使用join操作之后,再进行数据过滤。

SQL执行顺序

下面是一条我们经常会用到也经常会手写的一条sql语句。

select distinct
    查询列表(要查的字段),
    max(), avg().... 聚合函数
from
    左边的表们s
连接类型(left|inner) join 
    右边的表们s
on 
    连接条件
where
    筛选条件
group by
    分组的列表(按什么字段分组)
having
    having_condition
order by
    排序的字段
limit
	pageSize

下面是sql语句的执行顺序

语法格式语法含义执行顺序
select查询语句8
distinct去重9
sum(), avg()…聚合函数6
from tableA主表1
join tableB连接3
on连接条件2
where过滤条件4
group by分组5
havinghaving条件7
order by排序10
limit分页11

查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入

  • 首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表 vt1(选择相对小的表做基础表)。
  • 接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2 。
  • 如果是outer join 那么这一步就将添加外部行,left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3 。
  • 如果 from 子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3。
  • 应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4。
  • 注意where与on的区别:先执行on,后执行where;on是建立关联关系在生成临时表时候执行,where是在临时表生成后对数据进行筛选的。
  • group by 子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。
  • 应用avg或者sum选项,为vt5生成超组,生成vt6.
  • 应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。
  • 处理select子句。将vt7中的在select中出现的列筛选出来。生成vt8.
  • 应用distinct子句,对vt8进行去重,生成vt9。
  • 应用order by子句。按照order_by_condition排序vt9,此时返回的一个游标,而不是虚拟表。
  • 应用limit选项。生成vt10返回结果给请求者即用户。

MySQL的执行顺序

SELECT语句定义

一个完整的SELECT语句包含可选的几个子句。SELECT语句的定义如下:

<SELECT clause> 
[<FROM clause>] 
[<WHERE clause>] 
[<GROUP BY clause>] 
[<HAVING clause>] 
[<ORDER BY clause>] 
[<LIMIT clause>] 

SELECT子句是必选的,其它子句如WHERE子句、GROUP BY子句等是可选的。 

一个SELECT语句中,子句的顺序是固定的。例如GROUP BY子句不会位于WHERE子句的前面。 

SELECT语句执行顺序

SELECT语句中子句的执行顺序与SELECT语句中子句的输入顺序是不一样的,所以并不是从SELECT子句开始执行的,而是按照下面的顺序执行:

开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->SELECT子句->ORDER BY子句->LIMIT子句->最终结果

每个子句执行后都会产生一个中间结果,供接下来的子句使用,如果不存在某个子句,就跳过

对比了一下,MySQL和sql执行顺序基本是一样的, 标准顺序的 SQL 语句为:

select empName, max(salary) as maxSalary 
from t_emp 
where empName is not null 
group by empName 
having max(salary) > 2000 
order by maxSalary

在上面的示例中 SQL 语句的执行顺序如下:

(1). 首先执行 FROM 子句, 从 t_emp 表组装数据源的数据

(2). 执行 WHERE 子句, 筛选 t_emp 表中所有数据不为 NULL 的数据

(3). 执行 GROUP BY 子句, 把 t_emp 表按 empName 列进行分组

​ (注:这一步开始才可以使用select中的别名,他返回一个游标,而不是一个表,所以在where中不可以使用select中的别名,而having却可以使用)

(4). 计算 max() 聚集函数, 按 maxSalary 求出总薪酬中最大的一些数值

(5). 执行 HAVING 子句, 筛选员工的总薪酬大于 2000的.

(7). 执行 ORDER BY 子句, 把最后的结果按 maxSalary 进行排序.

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql如何查询两个日期之间最大的连续登录天数

    mysql如何查询两个日期之间最大的连续登录天数

    在现在的很多网站中都有这样一个功能。记录用户的连续登陆天数,所谓的连续在线是指相邻两天都登录过,不一定一直在线,但是只要有过登录即可。这篇文章主要介绍的是利用sql语句如何查询在两个日期之间最大的连续登录天数,有需要的朋友们下面来一起看看吧。
    2016-10-10
  • 貌似很强的mysql备份策略分享

    貌似很强的mysql备份策略分享

    貌似很强的mysql备份策略,号称天下无敌,哈哈,有需要的朋友参考下吧
    2013-02-02
  • MySQL分区表分区策略详解

    MySQL分区表分区策略详解

    这篇文章主要介绍了MySQL分区表分区策略详解,分区是一种表的设计模式,通俗地讲表分区是将一大表,根据条件分割成若干个小表。但是对于应用程序来讲,分区的表和没有分区的表是一样的,需要的朋友可以参考下
    2023-07-07
  • MySQL常用日期时间函数示例详解

    MySQL常用日期时间函数示例详解

    MySQL提供了大量的日期和时间函数,这些函数用于在查询中处理和操作日期与时间值,这篇文章主要介绍了MySQL常用日期时间函数,需要的朋友可以参考下
    2024-06-06
  • Mysql给普通分页查询结果加序号实操

    Mysql给普通分页查询结果加序号实操

    这篇文章主要介绍了Mysql给普通分页查询结果加序号实操,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • DBA应该知道的一些关于SQL Server跟踪标记的使用

    DBA应该知道的一些关于SQL Server跟踪标记的使用

    本篇文章小编为大家介绍,DBA应该知道的一些关于SQL Server跟踪标记的使用。需要的朋友参考下
    2013-04-04
  • MySQL死锁产生的原因和解决方法

    MySQL死锁产生的原因和解决方法

    死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,本文就给大家介绍一下MySQL死锁产生的原因和解决方法
    2023-07-07
  • MySQL数据库中遇到no database selected问题解决办法

    MySQL数据库中遇到no database selected问题解决办法

    这篇文章主要给大家介绍了关于MySQL数据库中遇到no database selected问题的解决办法,这是MySQL数据库的错误提示,意思是没有选择数据库,在使用MySQL命令行操作时需要先选择要操作的数据库,否则就会出现这个错误,需要的朋友可以参考下
    2024-03-03
  • mysql source 命令导入大的sql文件的方法

    mysql source 命令导入大的sql文件的方法

    本文将详细介绍mysql source 命令导入大的sql文件的方法;需要的朋友可以参考下
    2012-11-11
  • mysql常用函数之group_concat()、group by、count()、case when then的使用

    mysql常用函数之group_concat()、group by、count()、case whe

    本文主要介绍了mysql常用函数之group_concat()、group by、count()、case when then的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01

最新评论