条件计数:使用SUM()和COUNT()的性能差异?

时间:2012-07-05 08:28:09

标签: sql count query-optimization

就像一个非常简单的例子,假设我有表test,其中包含样本数据,如下所示:

a     |     b      
-------------
1     |    18
1     |    24
1     |    64
1     |    82
1     |    10
1     |     7
2     |     5
2     |    18
2     |    66
2     |    72
3     |    81
3     |    97

对于每个a,我要计算其中b的数量是多少a | bcnt -------------- 1 | 4 2 | 2 3 | 0 。 50.结果如下:

SELECT a, COUNT(CASE WHEN b < 50 THEN 1 ELSE NULL END) AS bcnt
FROM test
GROUP BY a

现在我可以通过两种方式实现这一结果:

SELECT a, SUM(CASE WHEN b < 50 THEN 1 ELSE 0 END) AS bcnt
FROM test
GROUP BY a

或者:

{{1}}

我知道这可能看起来像是一个微不足道的小问题,但我的问题是,在使用一种方法而不是另一种方法方面会有任何优势(无论多么轻微):性能?......他们有多少其他DBMS会工作吗?......陈述的清晰度......等等。

4 个答案:

答案 0 :(得分:7)

  

性能?

哦,差别,如果有的话,将是微不足道的,我敢肯定。我无需担心。

  

他们可以使用多少个其他DBMS?

我毫不怀疑它们至少可以在任何主要的 SQL产品中运行,所以,这不是一个值得关注的事情,不管怎么说都不是我。

  

陈述的清晰度?

当然COUNT表示您想要计算事情更清楚,而不是加起来某些任意值。使用SUM,只有在浏览完条件后才能到达THEN 1部分,您才会意识到实际意图。

此外,如果我使用COUNT,我可以省略ELSE NULL部分,因为这是ELSE缺席时隐含的内容。如果我在ELSE 0表达式中省略SUM,我最终可能会得到NULL结果而不是可能预期的0

另一方面,可能是完全相反的情况,因为计数结果会更方便地返回NULL而不是0。因此,如果我使用COUNT,我必须执行类似NULLIF(COUNT(CASE ...), 0)的操作,而使用SUM(CASE ...)时,只需省略ELSE子句即可。但即使在这种情况下,我仍然可能更喜欢稍微更清晰一点的简洁(其他条件相同)。

答案 1 :(得分:3)

就个人而言,我会使用

select a, count(b)
  from test
 where b < 50
 group by a

清晰,简洁,根据这个SQL fiddle比其他人快一点(根据执行计划需要更少的数据,但是有一个很小的表,你不会注意到差异):

答案 2 :(得分:2)

where子句有什么问题:

select a, count(b)
from test
where b < 50
group by a

答案 3 :(得分:-1)

使用COUNT计算元素,使用SUM为可能为负的结果添加数字(正数,负数或零)。