2011-10-05 34 views
4

我想知道在存储过程中实现“IF”条件的更好方法。如果改善查询计划重用的条件,首选的T-SQL方法

我见过这种方法广泛使用。我喜欢这相当于迭代译码...

declare @boolExpression bit = 1 --True 

if @boolExpression = 1 
    select column from MyTable where group = 10 
else 
    select column from MyTable where group = 20 

使用一组为基础的方法...

declare @boolExpression bit = 1 --True 

select column from MyTable where group = 10 and @boolExpression =1 
union all 
select column from MYTable where group = 20 and @boolExpression =0 

我喜欢,因为我了解使用此方法创建一个可重复使用查询计划和更少的计划缓存流失。这是事实还是虚构?哪一个是正确的使用方法。

在此先感谢

+1

你是否错过了第二个'UNION ALL'? –

+0

是的,谢谢Martin,UNION ALL丢失了。我将它添加到 –

回答

4

假设你缺少一个UNION ALL没有在它很多,据我可以看到。第一个版本将缓存每个语句的计划,作为COND运算符的子元素,以便在执行时仅调用相关的语句。

Plan 1 screenshot

第二个将有两个分支作为连接运算符的孩子。这些过滤器具有启动表达式谓词,意思是每个寻道只在需要时才被评估。

Plan 2 screenshot

+0

位参数有1或0值,所以为什么结合时,其中一个选择语句总是会返回0行? –

+1

@Adrian - 所以只返回一个结果集。而不是返回2个结果集 - 一个空的和一个包含数据。 –

+0

好的,我明白了,第一次当我看到这个技巧 –

0

你也可以按如下方式使用它:

DECLARE @boolExpression BIT = 1 

SELECT column FROM MyTable 
WHERE 
    CASE 
     WHEN @boolExpression = 1 THEN 
      CASE 
       WHEN group = 10 THEN 1 
       ELSE 0 
      END 
     ELSE 
      CASE 
       WHEN group = 20 THEN 1 
       ELSE 0 
      END 
    END = 1 

我知道这看起来复杂,但做的伎俩,尤其是在-情况下,当一个存储过程的参数将被可选的。

+0

这是不可纠正的,并将扫描不寻求。 –

+0

@Martin Smith:感谢您的评论,我同意这将是一次扫描。只是想在WHERE子句中描述条件操作的另一种方式,因为更容易维护更改,直到和除非性能成为一个真正的问题,这可能会改变对象的实际需求/需求;这在问题中并不明确。 –

+0

我的眼睛正在浇水。 –