如何使用SQL Server SUM函数避免额外的时间成本



我意识到我的查询每次使用SUM函数都需要指数时间。。。

例如,以下代码需要2秒

SELECT sub.a, SUM(sub.b)
FROM (
SELECT a, b, c 
FROM temp
)sub 
GROUP BY a;

使用第二个SUM现在需要4秒,依此类推…

SELECT sub.a, SUM(sub.b), SUM(sub.c)
FROM (
SELECT a, b, c 
FROM temp
)sub 
GROUP BY a;

我做的每一个SUM似乎都在再次执行子查询,无论这是否正确,避免时间成本的最佳做法是什么?

上面的例子只是以最基本的方式表示问题

TL;DR:不,这是完全错误的

当您在SQL Server中运行查询时,优化器会将其编译为它能找到的最有效的方法。您可以通过单击SSMS中的Include Actual Execution Plan来查看结果。

对于您指定的查询,它通常会执行以下操作:

  1. 它注意到子查询可以内联到查询中,并且这样做:
SELECT sub.a, SUM(sub.b), SUM(sub.c)
FROM temp
GROUP BY a;
  1. 然后,它通过a值评估聚合表的最佳方式。假设根本没有索引,这里很可能会选择Hash Aggregate

  2. 在执行时,每一行都被馈送到Hash中,Hash构建了一个内存中的哈希表,以a值为键。每一行都是基于a查找的,如果以前从未见过,则会向哈希表中添加一个键。然后CCD_ 6和CCD_。

  3. 假设您在a,b,c上有一个索引。现在有了一种更快的方法,称为Stream Aggregate,因为现在值通过按a排序的Aggregate。

  4. 每一行都通过聚合。如果a的值与前一行相同,那么它的bc的值将添加到我们迄今为止所拥有的值中。当a值发生变化时,将输出现有结果,然后我们再次开始聚合。

确实,对额外的列求和是额外的开销,但与读取磁盘表或哈希相比,这相当小,因为整个查询只进行一次哈希。

最新更新