带有CASE的SQL SUM或COUNT - 效率更高

时间:2014-04-25 04:23:37

标签: sql-server sql-server-2008-r2 count sum case

如果我有一个SQL Server 2008 R2数据库表,主键为subject_idINT)和category_idINT),并且列有点面具(是的,恐怖的恐怖有点面具!,但它就是这样,位掩码不会吓到我,以及为清晰而省略的其他列...)

鉴于以下两个问题,哪个更有效?我尝试使用客户端统计信息和执行计划输出,但每次运行查询时统计信息似乎都有所不同,并且本身并未指出明显的赢家。

查询1:

SELECT SUM( CASE WHEN ( category_id = 1 AND ( bit_mask & 4 ) = 4 ) THEN 1
                 WHEN ( category_id = 2 AND ( bit_mask & 8 ) = 8 ) THEN 1
                 ELSE 0 END )
FROM data_tbl
WHERE subject_id = 12;

查询2:

SELECT COUNT(*)
  FROM data_tbl
 WHERE subject_id = 12
   AND 1 = ( CASE WHEN ( category_id = 1 AND ( bit_mask & 4 ) = 4 ) THEN 1
                  WHEN ( category_id = 2 AND ( bit_mask & 8 ) = 8 ) THEN 1
                  ELSE 0 END );

如果某个SQL专家可以查看并立即告诉哪个查询更有效(或者它们是否相同?),请告诉我。

提前致谢!

3 个答案:

答案 0 :(得分:0)

都不是。这应该胜过两者:

SELECT COUNT(*)
FROM data_tbl
WHERE subject_id = 12
AND (
  (category_id = 1 AND ( bit_mask & 4 ) = 4 ) 
  OR 
  (category_id = 2 AND ( bit_mask & 8 ) = 8 )
)

原因是此查询为优化器提供了使用索引或其他方法处理逻辑的更好机会。您的查询会将计数逻辑埋没在优化程序无法触及的计算中。

答案 1 :(得分:0)

与往常一样,它主要取决于基数和选择性。我的猜测是第二个人有更快的机会。根据您的实际数据检查执行计划以确定。

然而,最快的变体可能就是这个:

SELECT SUM( CASE WHEN ( category_id = 1 AND ( bit_mask & 4 ) = 4 ) THEN 1
                 WHEN ( category_id = 2 AND ( bit_mask & 8 ) = 8 ) THEN 1
                 ELSE 0 END )
FROM data_tbl
WHERE subject_id = 12
AND category_id in (1, 2);

同样,它只是一个猜测,它可能很容易被UNION ALL(每个category_id一个SELECT)胜出。

答案 2 :(得分:0)

好的 - 感谢大家的回复 - 我测试了所提供的建议,下面是查询分析器报告的结果:

查询1:

SELECT SUM( CASE WHEN ( category_id = 1 AND ( bit_mask & 4 ) = 4 ) THEN 1
                 WHEN ( category_id = 2 AND ( bit_mask & 8 ) = 8 ) THEN 1
                 ELSE 0 END )
 FROM data_tbl
WHERE subject_id = 12
  AND category_id in ( 1, 2);

10次试验后的平均“总执行时间”:10.8

查询2:

SELECT COUNT(*)
 FROM data_tbl
WHERE subject_id = 12
  AND ( ( category_id = 1 AND ( bit_mask & 4 ) = 4 ) OR 
        ( category_id = 2 AND ( bit_mask & 8 ) = 8 ) );

10次试验后的平均“总执行时间”:11.6

奇怪的是,两种情况下执行计划看起来都相同。所以它看起来像查询1将成为一个。