条件聚合数据库查询及其性能影响

时间:2014-01-29 18:18:16

标签: sql sql-server database performance tsql

我认为这个问题最好用一个例子来询问:如果你想要一个表中的两个计数 - 比如说所有的行都有一个位标志设置为false而另一个所有的那些都设置为true - 是否有一个这种查询的最佳实践以及可以采取的任何方法的性能影响是什么?

为了进一步扩展,并从以下文章开始,如何从性能的角度将单独的查询与CASE列表中SELECT评估的版本进行比较?还有其他方法吗?

http://www.codeproject.com/Articles/310674/Conditional-Sums-in-SQL-Aggregate-Methods

2 个答案:

答案 0 :(得分:1)

SELECT [bitCol], count(*)
  FROM [table]
 GROUP BY [bitCol]

如果该列已编入索引,则为索引扫描,后跟流聚合 怀疑你可以做得更好

答案 1 :(得分:1)

除了Blam的方式,我认为有三种基本方法可以获得理想的结果。我测试了以下三个选项以及我系统上的Blam。我发现的结果如下。另外,旁注,我们的系统中没有任何位数据,因此我计算了一个带有两个值(“H”或“R”)的索引列。

使用条件聚合方法可以获得最快的性能。使用Blam的Grouping和Aggregate方法导致第二快的方式,比条件聚合长约33%。两个单独的选择语句方法是第三快的,始终比条件聚合长近50%。最后,Joins方法耗时最长,比条件聚合慢近1000%。当你多次加入那张桌子时,预期(由我)加入的时间最长。我加入这种方法的原因是因为在问题中没有讨论(可能是因为显而易见的原因);抛开所有性能问题,如果不是极其缓慢的选择,它是可行的。两个单独的select语句也是有意义的,因为您正在运行两个单独的聚合,分别访问该表两次。

我不确定是什么导致了条件聚合方法和Blam方法之间的差异。我一直对案例陈述的速度和表现感到惊喜,今天也没有什么不同。

我认为除了性能考虑之外,case语句方法可能是最通用的方法。它允许您使用几乎任何类型的字段并有助于选择值的子集,而Blam的使用Aggregate方法的分组将显示所有可能的列值,除非包含Where子句。

条件聚合

Select SUM(Case When bitcol = 1 Then 1 Else 0 End) as True_Count
    , SUM(Case When bitcol = 0 Then 1 Else 0 End) as False_Count

From Table;

两个单独的选择语句

Select Count(1) as True_Count

From Table

Where bitcol = 1;

Select Count(1) as False_Count

From Table

Where bitcol = 0;

使用联接

Select Count(T2.bitcol) as True_Count
    , Count(T3.bitcol) as False_Count

From Table T1
Left Outer Join Table T2
    on T1.ID = T2.ID
Left Outer Join Table T3
    on T1.ID = T3.ID;