聚合重复与嵌套查询

时间:2014-11-27 03:07:10

标签: mysql sql

我有一个查询如下:

SELECT SUM(`weight`) as totalgrams,
       SUM(`weight`)/1000 as totalkilograms
FROM `item`

这要求我使用第一列SUM的结果,但由于我无法使用totalgrams,我需要再次重做SUM功能在第二列计算中。
来自EXPLAIN的查询计划: enter image description here

现在,使用第二个查询:

SELECT totalgrams, totalgrams/1000 as totalkilograms
FROM (SELECT SUM(`weight`) as totalgrams
       FROM `item`) prequery

我不需要重复SUM,但我最终得到了一个嵌套查询。
来自EXPLAIN的查询计划: enter image description here

乍一看,似乎最好使用第一个查询,因为它在执行计划中只有一个条目,但是SUM在这里计算了两次(这是多余的,不可扩展的)?
或者实际上系统已经对此进行了优化并且只计算一次;所以第一个查询确实更好吗?

现在表格内只有几行,所以在实际[ms]单位中差异可能不大。
但如果以后它变得很大,我想知道哪个查询会更好? 它是否适用于所有DBMS?

纯粹是为了理解SQL工作流程,我们非常感谢任何见解。

2 个答案:

答案 0 :(得分:2)

MySQL实现了from子句中的子查询 - 即所谓的派生表。在这种情况下,摘要有一行一列,所以这没什么大不了的。

sum()中包括select两次没有此开销。从解释输出中不清楚sum()是否计算一次或两次。可能两次,但可能有一个优化步骤,消除了这种处理。无论如何,sum()非常便宜。昂贵的部分是安排聚合,所有聚合功能一起处理。

答案 1 :(得分:1)

你说这纯粹是为了理解工作流程,所以我会开始回答说mySQL确实有优化这些操作的方法,并且会这样做但是它并不完美,你不应该依赖它。 [PICKY]这个例子并不是最好的,因为总和操作无论如何都是微不足道的[/ PICKY]

我会说你的第一个解决方案更好,但更好的是根本不需要计算。大多数情况下,当使用计算列时,在获取结果的应用程序中编码计算更简单,即如果从php调用,则让php计算总公斤而不是mysql。它是基于单个返回值的一次性计算,无论mySQL是否优化都无关紧要。正如我之前所说的那样,总和是便宜的,所以对于这个特殊的例子它并不相关,但如果操作更昂贵,那将是一个因素,对于一般政策,我们不应该假设操作的微不足道。

如果外部语言是个问题,另一种可能性是创建一个中间表,然后用结果更新该表。在这种情况下(单行),开销使得这不太合乎需要,但如果结果表中有很多行(例如使用group by),或者创建一般策略,则开销就成了一个问题。