我发现这篇文章解释了在SP中使用IF / ELSE语句会导致性能下降,因为每个“分支”使用单独的SP。 http://sqlmag.com/t-sql/if-statements-and-stored-procedure-performance
但我有一个SP,从同一个表中选择相同的列,只有WHERE子句根据存在的变量而改变。这是一个例子:
IF @Variable1 IS NOT NULL
BEGIN
SELECT
*
FROM
dbo.Table1
WHERE
Column1 = @Variable1
END
ELSE IF @Variable1 IS NULL AND @Variable2 IS NOT NULL
BEGIN
SELECT
*
FROM
dbo.Table1
WHERE
Column1 = Column1
AND
Column2 = @Variable2
END
所以在这个例子中,最好有两个单独的SP来处理不同的变量,还是可以将它们全部放在这样的一个?
(我知道使用SELECT *
并不是一种好的做法。我只是为了举例而做的)
答案 0 :(得分:4)
通常情况下,我不会担心这一点,尽管你应该看一下Mikael Eriksson引用的白皮书,该白皮书有关于这个主题的大量有用信息。但是,我会删除Column1 = Column1
分支中的else
语句,因为这可能会使优化器混淆。
本文所指的是存储过程在第一次运行时编译的事实。这可能会产生不正常的结果。例如,如果第一次调用表时该表为空,那么优化器可能更喜欢将全表扫描更改为索引查找,这会因表变大而变坏。
问题可能是其中一个分支获得了次优的性能计划,因为数据在第一次调用时并不典型。如果其中一个值为NULL
,则尤其如此。这不仅发生在if
,而且这是您需要对问题敏感的一种情况。
我会推荐以下内容:
对于您的示例,table1(column1)
和table1(column2)
上的索引就足够了。
建议的摘要不是在您发现问题之前解决此问题。将逻辑放入两个存储过程应该是修复您实际看到的问题,而不是预先解决可能永远不存在的问题。如果您采用双过程方法,您仍然可以使用单个接口来调用每个过程,因此您仍然拥有相同的API。换句话说,一个程序应该变成三个而不是两个。