【问题标题】:Stored procedure causing timeout only when run from application仅在从应用程序运行时导致超时的存储过程
【发布时间】:2009-01-22 10:11:33
【问题描述】:

我们遇到了一个 sp 问题。

我们有一个非常简单的 sp,其中包含一个声明的表和几个最终返回 20 到 100 行的外连接。

由于查询此 sp 在生产环境和测试环境中都给我们带来了较差的性能,我们最近重写了它以提高效率,并在我们的测试环境中进行了彻底的测试并具有出色的性能。

我们将它发布到生产环境中只是为了发现它仍然很慢并且导致我们的 .NET 2.0 应用程序在被调用时超时。

我们什么都不懂,然后进入生产数据库上的 Management Studio 并在那里运行 sp,它在 1 秒内执行。

也就是说,当从我们的应用程序运行时,它非常慢并导致超时,当从 Management Studio 运行时,它非常快,从不超过一秒钟。

任何对 SQL Server 2005 有深入了解的人可以给我们一些提示吗?

【问题讨论】:

  • 当您说您在管理工作室中测试 SP 时,您是使用 EXEC 调用 SP 并提供一些参数,还是只是使用 SP 内部的查询正文?
  • 您是否在 SSMS 中使用与应用连接的同一用户进行了测试?

标签: .net sql-server performance stored-procedures .net-2.0


【解决方案1】:

我认为您的问题可能是“参数嗅探”。 它是 SQL Server 的执行环境在编译或重新编译期间“嗅探” sp 的参数值以生成更快的执行计划的过程。但有时它会得到一个参数组合,这些参数与 sp 将返回的当前数据一起构成一个非常慢的 sp。

那里有几个很好的解释。在 Stackoverflow 上搜索。 这是一个很好的: http://omnibuzz-sql.blogspot.com/2006/11/parameter-sniffing-stored-procedures.html

一种可能的解决方案是在 sp 中创建局部变量并将传入的参数值设置为它们。然后只使用 sp 中的局部变量。

CREATE PROCEDURE [dbo].spTest
  @FromDate as DATETIME
AS
BEGIN
  DECLARE @FromDate_local as DATETIME
  SET @FromDate_local = '2009-01-01'

  SET @FromDate_local = @FromDate
  ...
  SELECT * FROM TestTbl WHERE FromDate >= @FromDate_local
END

【讨论】:

  • 谢谢!我遇到了这个确切的问题,您的解决方案效果很好!
【解决方案2】:

重新编译是一种钝器。很有可能是参数嗅探

看到这个问题:Stored Procedure failing on a specific user

【讨论】:

    【解决方案3】:

    感谢各位的回复,运行 sp_recompile 似乎解决了问题,至少自从我昨天下午执行以来,一切都运行得很顺利,会继续关注它,看看它是否保持快速。

    但是不明白当我更改 sp 中的内容时没有重新编译?

    【讨论】:

      【解决方案4】:

      确保您的生产数据库具有最新的统计信息并且索引状况良好(如果可能,请考虑重建所涉及的索引)。

      【讨论】:

        【解决方案5】:

        您能确定没有发生死锁情况吗?管理工作室的运行将与应用程序隔离,这可能是更大事务的一部分。

        【讨论】:

          【解决方案6】:

          我建议您在 SSMS 中更改您的首选项,以便您在默认情况下连接 ARITHABORT OFF 以避免这种混淆。但实际上与应用程序具有相同设置有一个小缺点:您可能没有观察到性能问题与参数嗅探有关。但是,如果您在调查性能问题时习惯于在打开和关闭 ARITHABORT 的情况下运行问题程序,您可以轻松断定是否涉及参数嗅探。

          查看这些链接: https://www.sommarskog.se/query-plan-mysteries.html#sniffinfo

          https://docs.microsoft.com/en-us/sql/t-sql/statements/set-arithabort-transact-sql?view=sql-server-ver15

          【讨论】:

          • 我认为这个问题的现有回复比上面的答案更准确
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-05
          • 2012-01-10
          • 1970-01-01
          • 1970-01-01
          • 2012-08-26
          • 1970-01-01
          相关资源
          最近更新 更多