“IF..ElseIf..Else”或“Where子句”指导存储过程结果

发布于 2024-10-01 02:33:19 字数 566 浏览 0 评论 0原文

我有以下两个 SQL 语句

第一个:

IF(@User_Id IS NULL)  
BEGIN  
      SELECT *
      FROM [UserTable]
END  
ELSE           
BEGIN                  
      SELECT *
   FROM  [UserTable] AS u
   WHERE  u.[Id] = @User_Id                  
END 

第二个:

SELECT  *
FROM [UserTable] AS u
WHERE (@User_Id IS NULL OR u.[Id] = @User_Id)

这两个查询都将包装在其自己的存储过程中。我怀疑 IF 语句导致 SQL 上的大量重新编译。我面临着要么将 IF 语句的每个部分分离成自己的存储过程,要么用 WHERE 子句替换整个 IF 语句(如上面第二个 SQL 语句所示)

我的问题是:这两个语句之间有什么区别从性能角度来看,SQL 将如何处理每个语句?

谢谢。

I have the following two SQL statements

First one:

IF(@User_Id IS NULL)  
BEGIN  
      SELECT *
      FROM [UserTable]
END  
ELSE           
BEGIN                  
      SELECT *
   FROM  [UserTable] AS u
   WHERE  u.[Id] = @User_Id                  
END 

Second one:

SELECT  *
FROM [UserTable] AS u
WHERE (@User_Id IS NULL OR u.[Id] = @User_Id)

Both of those queries would be wrapped in its own stored procedure. I am suspecting that the IF statement is causing a lot of recompilations on SQL. I am faced with either separating each part of the IF statement into its own stored procedure, OR replacing the entire IF statement with a WHERE clause (illustrated above in the second SQL statement)

My question is: What is the difference between the two statements from a performance perspective, and how would SQL treat each statement?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清君侧 2024-10-08 02:33:19

两种解决方案都会生成相同数量的编译。

第一个解决方案是查询优化器可以自由地为两个不同的查询中的每一个提出最佳计划。第一个查询(在 IF 的 NULL 分支上)没有太多可优化的地方,但第二个查询(在 ID 的 NOT NULL 分支上)可以优化,如果 Id 列上有索引存在。

但第二种解决方案是一场优化灾难。无论@User_Id 参数的值是什么,优化器都必须提出一个适用于该参数的任何值的计划。因此,无论 @User_Id 的值如何,该计划都将始终使用次优表扫描。这个问题没有办法解决,这不是某些人可能认为的参数嗅探。只是计划的正确性,即使计划生成时的值不为空,即使参数 NULL,计划也必须工作,因此它不能使用Id 上的索引。

总是,总是,总是,使用带有显式 IF 的第一种形式。

Both solution will generate identical number of compilations.

The first solution the query optimizer is free to come up with the best plan for each of the two, different, queries. The first query (on the NULL branch of the IF) is not much that can be optimized, but the second one (on the NOT NULL branch of the ID) can be optimized if an index on Id column exists.

But the second solution is an optimization disaster. No matter the value of the @User_Id parameter, the optimizer has to come up with a plan that works for any value of the parameter. As such, no matter the value of @User_Id, the plan will always use the suboptimal table scan. There is just no way around this issue, and this is not parameter sniffing as some might think. Is just correctness of the plan, even if the value at plan generation time is NOT NULL, the plan has to work even when the parameter is NULL, so it cannot use the index on Id.

Always, always, always, use the first form with the explicit IF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文