我有一个查询如下:
SELECT SUM(`weight`) as totalgrams,
SUM(`weight`)/1000 as totalkilograms
FROM `item`
这要求我使用第一列SUM
的结果,但由于我无法使用totalgrams
,我需要再次重做SUM
功能在第二列计算中。
来自EXPLAIN
的查询计划:
现在,使用第二个查询:
SELECT totalgrams, totalgrams/1000 as totalkilograms
FROM (SELECT SUM(`weight`) as totalgrams
FROM `item`) prequery
我不需要重复SUM
,但我最终得到了一个嵌套查询。
来自EXPLAIN
的查询计划:
乍一看,似乎最好使用第一个查询,因为它在执行计划中只有一个条目,但是SUM
在这里计算了两次(这是多余的,不可扩展的)?
或者实际上系统已经对此进行了优化并且只计算一次;所以第一个查询确实更好吗?
现在表格内只有几行,所以在实际[ms]单位中差异可能不大。
但如果以后它变得很大,我想知道哪个查询会更好?
它是否适用于所有DBMS?
纯粹是为了理解SQL工作流程,我们非常感谢任何见解。
答案 0 :(得分:2)
MySQL实现了from
子句中的子查询 - 即所谓的派生表。在这种情况下,摘要有一行一列,所以这没什么大不了的。
在sum()
中包括select
两次没有此开销。从解释输出中不清楚sum()
是否计算一次或两次。可能两次,但可能有一个优化步骤,消除了这种处理。无论如何,sum()
非常便宜。昂贵的部分是安排聚合,所有聚合功能一起处理。
答案 1 :(得分:1)
你说这纯粹是为了理解工作流程,所以我会开始回答说mySQL确实有优化这些操作的方法,并且会这样做但是它并不完美,你不应该依赖它。 [PICKY]这个例子并不是最好的,因为总和操作无论如何都是微不足道的[/ PICKY]
我会说你的第一个解决方案更好,但更好的是根本不需要计算。大多数情况下,当使用计算列时,在获取结果的应用程序中编码计算更简单,即如果从php调用,则让php计算总公斤而不是mysql。它是基于单个返回值的一次性计算,无论mySQL是否优化都无关紧要。正如我之前所说的那样,总和是便宜的,所以对于这个特殊的例子它并不相关,但如果操作更昂贵,那将是一个因素,对于一般政策,我们不应该假设操作的微不足道。
如果外部语言是个问题,另一种可能性是创建一个中间表,然后用结果更新该表。在这种情况下(单行),开销使得这不太合乎需要,但如果结果表中有很多行(例如使用group by),或者创建一般策略,则开销就成了一个问题。