MySQL学习-函数(十六)

85 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

前言

上篇我们又学习了一部分MySQL中的函数。有兴趣的小伙伴可以阅读(# MySQL学习-函数(十五))。
下面继续学习MySQL中的函数。

上一节,我们学习了HAVING的使用,得到了一些结论,其中有一条是在过滤条件中没有聚合函数时,WHERE的执行效率要高于HAVING。下面学习为什么WHERE的效率更高。

SQL的底层执行原理

SELECT语句的完整结构

SQL92语法

SELECT ..., ..., ...(聚合函数)
FROM ..., ..., ...
WHERE 多表的连接条件 AND 不包含聚合函数的过滤条件
GROUP BY ..., ...
HAVING 包含聚合函数的过滤条件
ORDER BY ..., ...(ASC / DESC)
LIMIT ..., ...

SQL99语法

SELECT ..., ..., ...(聚合函数)
FROM ... (LEFT / RIGHT) JOIN ... ON 多表连接条件
(LEFT / RIGHT) JOIN ... ON 多表连接条件
WHERE 不包含聚合函数的过滤条件
GROUP BY ..., ...
HAVING 包含聚合函数的过滤条件
ORDER BY ..., ...(ASC / DESC)
LIMIT ..., ...

我们编写SQL语句时需严格按照上面的顺序编写,否则会报错。

SQL语句的执行过程

SQL99语法顺序

FROM ..., ... -> ON -> (LEFT / RIGHT) JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY -> LIMIT

  1. 从上面的执行顺序就可以看出,如果把所有的过滤条件都写在HAVING中,那么所有的数据会先经过分组后再过滤。如果是写在WHERE中,那么会把数据先进行过滤,再做分组,做分组的数据相对于过滤前的数据,会少,效率肯定也更高。所以这也解释了开头的问题,WHERE的执行效率会比HAVING高。
  2. 上一节还有一个结论,WHERE不能使用分组函数。从顺序中就可以看出来,WHERE是在GROUP BY前执行的,这时候还没有进行分组,WHERE里肯定也不能使用分组函数了。
  3. 之前在写SQL语句中,我们还注意到WHERE中不能使用SELECT里面声明的别名,只能在ORDER BY中使用。从执行顺序中,我们就能知道原因了,SELECT在WHERE后执行,WHERE肯定不知道SELECT中声明的别名,ORDER BY在SELECT后执行,可以访问到SELECT中声明的别名。

今天先学习到这里,明天继续。