MySQL 查询常用操作(0) —— 查询语句的执行顺序

时间:2022-07-13 00:35:26

MySQL中明确查询语句的执行顺序极其重要,了解执行顺序才不至于犯一些简单错误,例如having 后面是否可以使用 select 中重命名的列名等问题。另外SQL中实际使用最频繁的就是查询(Queing),要想写出高质量、高性能的查询语句,必须深入地了解SQL的逻辑查询处理顺序和机制。

一、查询语句的执行顺序

基础查询语句

(5) select distinct top(<取数说明>) <选择 列表>
(1) from <表1> <连接类型> join <表2> ON <连接条件>
(2) where <筛选条件>
(3) group by <分组条件>
(4) having <条件>
(6) order by <排序的列、排序规则>
(7) limit <选择行>

注意

1、select:避免使用 select * 。按照需要进行数据查询,否则会导致查询速度变慢。避免查询多余数据。

2、where:因为还没有对数据进行分组,所以where 不能和聚合函数(count、sum、max等函数)一起使用,也不能引用 select 列表中创建的别名,因为 select 还没有执行。

3、group by 和 having:在 group by 和 having 中不可以直接使用select中重命名的列。

4、order by:但是在 order by 中可以直接使用select中重命名的列。

5、limit:如果只需要查询出一条数据,使用 limit 1。例如,想要知道是否有男生,只要能查询到一条含有男生的记录就可以。使用Limit 1 可以在找到一条数据后停止搜索,避免多余查询。

SQL并没有按照编写语句的顺序曲执行语句。上边的序号,就是查询语句在执行过程中处理逻辑的顺序。

二、查询处理机制

每个执行过程主要做那些事呢,下面具体介绍:

(1)FROM

该过程从数据库中选取需要查询的表或视图。并处理表运算符。

在涉及到联接运算的查询中(各种join),主要有以下几个步骤:

  • 求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(cross join),求笛卡儿积,生成虚拟表VT1-J1。
  • ON 筛选器。这个阶段对上个步骤生成的 VT1-J1 进行筛选,根据ON中出现的谓词进行筛选,让谓词取值为 true的行插入到VT1-J2。
  • 添加外部行。如果指定了 outer join,还需要将VT1-J2 中没有找到匹配的行,作为外部行添加到VT1-J2中,生成VT1-J3。

经过以上步骤,FROM 执行过程就完成了。

概括地讲,FROM 执行过程就是找到表并进行数据的预处理,根据条件对表进行处理。

(2)WHERE

从表或视图中筛选出满足条件的行。根据<筛选条件>中条件对 VT1中的行进行筛选,让满足条件的行插入到 VT2中。

(3)GROUP BY

根据指定的列对筛选出的行进行分组。按照指定的列名,将 VT2中的进行分组,生成VT3。最后每个分组只有一行。

(4)HAVING

从分组后的数据中筛选出满足条件的行。根据 having子句中出现的谓词对VT3的分组进行筛选,并将符合条件的组插入到 VT4中。

(5)SELECT

从表或视图中选取需要的列。这个阶段是投影的过程,处理select子句中提到的列,产生VT5。

一般按下列顺序进行:

  • 计算 select 列表中的表达式,生成VT5-1。
  • 若有 distinct,则删除VT5-1中的重复行,生成VT5-2。
  • 若有 top,则根据 order by 子句定义的逻辑顺序,从VT5-2 中选择签名指定数量或者百分比的行,生成VT5-3。

(6)ORDER BY

根据指定的列对筛选出的行进行排序。按照 order by 子句中指定的列名,对VT5中的行,进行排序,生成游标VC6。

(7)LIMIT

根据指定的条件对筛选出的行再次进行筛选。按照 limit 子句中指定的行的位置,对Vc6中的行进行选择,生成VT7。

参考

SQL查询执行顺序