【问题标题】:Conditional counting: Performance differences in using SUM() vs COUNT()?条件计数:使用 SUM() 与 COUNT() 的性能差异?
【发布时间】:2012-07-05 08:28:08
【问题描述】:

作为一个非常简单的例子,假设我有一个表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

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

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

我知道这似乎是一件微不足道的小事,但我的问题是,使用一种方法相对于另一种方法是否有任何优势(尽管如此微不足道):性能?......他们有多少其他 DBMS可以工作吗?...陈述的清晰性?...等等。

【问题讨论】:

  • “我想得到...的计数” 问就是回答? :-)

标签: sql count query-optimization


【解决方案1】:

性能?

哦,我敢肯定,差异(如果有的话)将是微不足道的。这对我来说没什么好担心的。

他们将在多少个其他 DBMS 中工作?

我毫不怀疑两者至少可以在任何主要 SQL 产品中工作,因此,这不再是一个问题,反正对我来说也不是问题。

表述清楚吗?

当然COUNT 更清楚地表达了您想要计数 事物,而不是累加 一些任意值。使用SUM,只有在略过条件后到达THEN 1部分时,您才会意识到实际意图。

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

另一方面,可能在完全相反的情况下返回NULL而不是0作为计数结果会更方便。所以,如果我使用COUNT,我将不得不做类似NULLIF(COUNT(CASE ...), 0) 的事情,而使用SUM(CASE ...) 就足以省略ELSE 子句。但即使在那种情况下,我可能仍然更喜欢稍微长一点的清晰而不是稍微模糊的简洁(其他条件相同)。

【讨论】:

    【解决方案2】:

    就个人而言,我会使用

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

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

    【讨论】:

      【解决方案3】:

      where 子句有什么问题:

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

      【讨论】:

      • 嗯?具有用于过滤聚合函数的结果。你是说在哪里?
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2021-07-04
        • 2016-12-24
        • 2010-11-08
        • 2013-02-06
        • 2012-06-06
        • 1970-01-01
        • 2012-08-21
        • 2016-09-07
        • 2011-12-17
        相关资源
        最近更新 更多