持续创作,加速成长!这是我参与「掘金日新计划 · 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
- 从上面的执行顺序就可以看出,如果把所有的过滤条件都写在HAVING中,那么所有的数据会先经过分组后再过滤。如果是写在WHERE中,那么会把数据先进行过滤,再做分组,做分组的数据相对于过滤前的数据,会少,效率肯定也更高。所以这也解释了开头的问题,WHERE的执行效率会比HAVING高。
- 上一节还有一个结论,WHERE不能使用分组函数。从顺序中就可以看出来,WHERE是在GROUP BY前执行的,这时候还没有进行分组,WHERE里肯定也不能使用分组函数了。
- 之前在写SQL语句中,我们还注意到WHERE中不能使用SELECT里面声明的别名,只能在ORDER BY中使用。从执行顺序中,我们就能知道原因了,SELECT在WHERE后执行,WHERE肯定不知道SELECT中声明的别名,ORDER BY在SELECT后执行,可以访问到SELECT中声明的别名。
今天先学习到这里,明天继续。