SQL中多分支If语句的性能(Sql Server 2008)

Posted

技术标签:

【中文标题】SQL中多分支If语句的性能(Sql Server 2008)【英文标题】:Performance of Multi-branch If Statement in SQL (Sql Server 2008) 【发布时间】:2016-12-09 14:52:07 【问题描述】:

我想知道是拥有多个存储过程更好,还是一个存储过程具有多个 if-else 分支。

我了解SQL Server会根据最近一次执行的存储过程创建一个执行计划,所以下次执行存储过程时,用不同的参数导致IF语句中的路径不同,那么将编译和缓存不同的执行计划。

我的主管说他想减少我们环境中存储过程的数量,并指示我们使用 if-else 语句来区分我们拥有数据的各个区域。 例如

if(@iso = 'Item1')
begin
    if(@type = 'A')
    begin
    end
    if(@type = 'B')
    begin
    end
    if(@type = 'C')
    begin
    end
end
if(@iso = 'Item2')
begin
    if(@type = 'A')
    begin
    end
    if(@type = 'D')
    begin
    end
end
if(@iso = 'Item3')
begin
    if(@type = 'B')
    begin
    end
    if(@type = 'E')
    begin
    end
end

在执行这个存储过程的时候,很有可能每次都会提交不同的参数。由于执行计划不断重新生成,这是否会导致大量数据库争用?

【问题讨论】:

减少存储过程数量的目的是什么?你从中得到什么?这是我要问的第一件事。 我不相信互联网上的人会告诉你你的两个过程中哪个更快。使用各种参数双向运行,并自行衡量性能差异。 这听起来很混乱,如果您在更新过程中出错,可能会破坏运行该过程的每个过程。这样做只会带来性能和维护方面的噩梦。 @mikeb 我们有大量的存储过程,所以主要是为了帮助维护。如果我们需要修改一个跨区域存在的流程,他觉得在一个存储过程中修改多行比在多个存储过程中修改一行更容易。 你说“他觉得在一个存储过程中修改多行比在多个存储过程中修改一行更容易”。这是一个糟糕的设计,IMO,你应该编写可重用的代码。如果您有共享逻辑,请使其成为其他 SP 调用的一个 SP。这样您就不必在多个地方更改多项内容,也不必管理一个单一的混乱 【参考方案1】:

我会为每个意图或目的投票支持单个存储过程。在大多数情况下,存储过程只有一个目的。这是有道理的。考虑“关注点分离”或SOLID 设计原则。它也将更容易维护。与较大或过于复杂的存储过程相比,理解和更改一些小型存储过程要容易得多。

如果您执行如上所述的具有多个参数的大型存储过程,则必须采取预防措施来防止参数嗅探和不良计划缓存的问题。这是 Brent Ozar 的一篇不错的文章,它很好地描述了问题以及如何解决它。 What is Parameter Sniffing?

【讨论】:

感谢您的回复。存储过程有一个单一的目的,即获得信用值。但是,我们有 5 个不同的区域,每个区域有 2-3 种不同的产品类型,每个区域都可以有自己的信用值。由于区域之间的源数据不同,这些值存储在数据库的不同表中。理想情况下,我们应该有一个数据仓库,其中所有数据都经过清理和规范化,但这必须等待未来。 听起来在那种情况下,我可能倾向于使用单个存储过程并根据输入动态构建 sql,这可能有点痛苦。也许利用一些 CTE 或表函数?我可能不得不用新信息改变我的投票。我可能倾向于同意你的主管。最好有一个单一的来源 (sproc) 来获取数据,然后让您的应用程序决定去哪里获取数据。最佳方法实际上取决于您的数据和业务逻辑。

以上是关于SQL中多分支If语句的性能(Sql Server 2008)的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server中多表连接时驱动顺序对性能的影响

Shell编程Shell中多分支case条件语句

sqlserver like '%' 性能问题

oracle pl/sql 控制结构(分支,循环,控制)

SQL报表语句中大量使用case when then end分支语句合适么?对性能有影响么

SQL Server - 条件语句的查询执行计划