1

我有这个查询(当然还有跨表的几个连接和一些视图,为了简单起见,我将它们称为 x)。

  1. 案例 1:select * from x -> 在 10 秒内返回,仍然可以接受,连接和大量数据相当繁重
  2. 案例2:select * from x where userid = 1->在0-1秒内返回,足够好
  3. 案例 3:使用 SP:if @userid = -1 select * from x else select from x where userid = @userid -> 现在使用参数用户 ID 1 调用 sp 应该在 0-1 秒内返回,因为它应该与案例 2 相当,但实际上它在 10 秒内返回。

    现在,参数屏蔽 OR WITH RECOMPILE on sp OR OPTION (recompile) on query with where 子句没有帮助,使 SP 运行得更快的userid = something原因是将 OPTION(recompile) 放在 SP 的第一部分,即在没有 where 的查询上条款。:

  4. 案例 4:使用 SP:if @userid = -1 select * from x option (recompile) else select * from x where userid = @userid

有什么解释吗?

我可以猜到它使用基于查询的优化而没有 where 子句,即使是带有 where 子句的查询,但这是为什么呢?

4

1 回答 1

1

存储过程缓存执行计划,因此它们没有每次调用 SP 时重新编译查询的开销。这在将存储过程用于事务时尤其重要。当查询运行几秒钟时,它就不那么重要了。

当查询采用参数时,存储过程必须决定要优化哪些值。我猜您的 SQL Server 将这两个查询识别为相同的,并为它们使用相同的缓存计划。它正在基于第一个查询优化计划。这是猜测,但它可以解释你所看到的。

您可以使用以下版本的查询轻松解决此问题:

select *
from x
where @userid = -1 or userid = @userid
option (recompile)
于 2012-09-19T18:18:46.520 回答