一个问题
在编写GROUP BY语句时,列属性可以使用聚合函数,如:
SELECT sex, MAX(score) FROM student GROUP BY sex;
该SQL语句的功能是统计学生中各个性别的最高分数。在这里有个直观的问题,MAX(score)语句是在前面的,GROUP BY语句是在后面的,为什么可以在GROUP BY语句执行完,即分组完成之后,再执行MAX函数进行统计?这就要说到SELECT语句中各子句的执行顺序了。
初步探究
在编写SELECT语句时,省略表名、列名和查询条件,顺序一般是这样的:
SELECT DISTINCT FROM JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT
在平时的编程习惯中,我们总会认为语句的执行顺序和编写顺序一致,但在SELECT语句中,实际的执行顺序是:
FROM JOIN ON WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY LIMIT
SELECT中个子句的执行顺序

执行顺序中,大致的逻辑是:获取所需数据 -> 对数据进行过滤 -> 对数据进行分组、排序等操作。
回到最开始的问题, MAX(score)由于是在SELECT操作中的,执行顺序在GROUP BY之后,所以可以在分组结束之后对列执行聚合函数。
执行顺序原理探析
为什么是这种执行顺序呢?
性能方面上
从性能方面上分析,这种先过滤后操作的执行顺序,可以使得最后操作数据时数据量得到减少,提高操作的性能。其次,DBMS在进行分组和排序时,对内存和处理器资源消耗较大,所以在分组和排序前减少数据量,DBMS可以更高效地管理内存和处理器资源。
关系代数理论基础上
关系代数操作包括有选择、投影、并、差、笛卡尔积、连接、分组和聚合,这些操作能与SQL语句中的子句对应:
- 选择 -> WHERE
- 投影 -> SELECT
- 并 -> UNION
- 笛卡尔积 -> 通过FROM和JOIN实现
- 连接 -> JOIN
- 分组和聚合 -> GROUP BY
在数据库原理中,关系代数优化是一个非常重要的过程,此步骤旨在通过重新排列和简化关系代数表达式来提高查询性能。关系代数优化最主要的思想是改变各个操作的执行顺序,如让选择操作尽可能早地进行,减少后续操作需要处理的数据量等。SELECT语句中的执行顺序也反映了这种思想。