【问题标题】:SQL query performance explanationSQL查询性能说明
【发布时间】:2012-09-19 16:25:57
【问题描述】:

我有这个查询(当然还有跨表的几个连接和一些视图,为简单起见,我将其称为 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 (重新编译)查询带有 where 子句没有帮助,是什么导致 使用userid = something 运行更快的SP 正在放置选项(重新编译) 在 SP 的第一部分,即没有 where 子句的查询。 :

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

有什么解释吗?

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

【问题讨论】:

  • 代码请使用代码块。 65题后你应该习惯了。
  • 感谢尼尔森的编辑!很抱歉没有把它放在代码块中。
  • 您是否要求我们解释您的疑问?为什么不只看 SSMS 中的执行计划?
  • 不,我问的是通过在不带 where 子句的查询中添加 option(recompile) 来提高性能的原因
  • 我的意思是,我猜这可能是从执行计划中计算出来的,我确实调查过但无法确定原因是什么。只需深入查看和分析执行计划,就可以理解很多问题(关于 stackoverflow 或其他问题)。但那我为什么要发布这个问题,如果你要我在这里附上执行计划,那就是另一回事了。

标签: sql sql-server sql-optimization database-optimization


【解决方案1】:

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

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

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

select *
from x
where @userid = -1 or userid = @userid
option (recompile)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多