30

这是我在另一个论坛上提出的一个问题,得到了一些不错的答案,但我想看看这里是否有人有更多的见解。

问题是您的 Web 应用程序中的一个页面在进行存储过程调用时超时,因此您使用 Sql Profiler 或您的应用程序跟踪日志来查找查询并将其粘贴到管理工作室以计算我们为什么它运行缓慢。但是你从那里运行它,它就会一直燃烧,每次不到一秒钟就返回。

我的特殊情况是使用 ASP.NET 2.0 和 Sql Server 2005,但我认为这个问题可能适用于任何 RDBMS 系统。

4

8 回答 8

29

这是我迄今为止从我的研究中学到的。

.NET 发送的连接设置与您在登录管理工作室时获得的设置不同。如果您使用 Sql Profiler 嗅探连接,您会看到以下内容:

-- network protocol: TCP/IP  
set quoted_identifier off  
set arithabort off  
set numeric_roundabort off  
set ansi_warnings on  
set ansi_padding on  
set ansi_nulls off  
set concat_null_yields_null on  
set cursor_close_on_commit off  
set implicit_transactions off  
set language us_english  
set dateformat mdy  
set datefirst 7  
set transaction isolation level read committed  

我现在将这些设置粘贴到登录到 sql server 时运行的每个查询的上方,以确保设置相同。

对于这种情况,我在断开连接和重新连接后分别尝试了每个设置,发现将 arithabort 从关闭更改为打开将问题查询从 90 秒减少到 1 秒。

最可能的解释与参数嗅探有关,这是 Sql Server 用来挑选它认为最有效的查询计划的一种技术。当您更改其中一个连接设置时,查询优化器可能会选择不同的计划,在这种情况下,它显然选择了一个错误的计划。

但我并不完全相信这一点。在更改此设置后,我尝试比较实际的查询计划,但我还没有看到差异显示任何更改。

在某些情况下,关于 arithabort 设置是否还有其他可能导致查询运行缓慢的内容?

解决方案似乎很简单:只需将 set arithabort 放在存储过程的顶部即可。但这可能会导致相反的问题:更改查询参数,突然它在“关闭”时运行得比“开启”更快。

目前我正在运行“重新编译”程序,以确保每次都重新生成计划。对于这个特定的报告来说没关系,因为重新编译可能需要一秒钟,而这对于需要 1-10 秒才能返回的报告来说并不太明显(这是一个怪物)。

但是对于运行更频繁并且需要在几毫秒内尽快返回的其他查询,这不是一个选项。

于 2008-08-13T16:01:51.730 回答
6

我有过类似的问题。尝试在 sproc create 上设置 with "WITH RECOMPILE" 选项,以强制系统在每次调用时重新计算执行计划。有时,查询处理器在具有大量分支或案例语句的复杂存储过程中会感到困惑,并且只会拉出一个真正次优的执行计划。如果这似乎“解决”了问题,您可能需要验证统计信息是最新的和/或分解存储过程。

您还可以通过分析存储过程来确认这一点。当您从 SQL Managment Studio 执行它时,IO 与您从 ASP.NET 应用程序分析它时相比如何。如果他们非常多,它只会重新强调它拉一个糟糕的执行计划。

于 2008-11-01T18:01:36.780 回答
2

您是否打开了 ASP.NET 跟踪?我有一个实例,问题不是 SQL 存储过程本身,而是该过程返回了 5000 行,而应用程序正尝试使用导致问题的 5000 个项目创建数据绑定 ListItems。

您还可以通过跟踪查看 Web 应用程序功能之间的执行时间,以帮助追踪事情。

于 2008-08-13T18:22:10.027 回答
2

我在使用 SQL 报告服务时遇到了同样的问题。尝试检查变量的类型,我正在向 SQL 发送不同类型的变量,比如将 varchar 发送到应该是整数的地方,或者类似的东西。在我同步了报表服务和 SQL 存储过程中的变量类型后,我解决了这个问题。

于 2008-09-16T14:44:43.687 回答
1

首先在暂存箱上进行测试,在服务器级别为 sql server 更改它

声明@option int

设置@option = @@options | 64

exec sp_configure '用户选项', @option

重新配置

于 2008-08-13T16:19:24.830 回答
0

您可以尝试使用 sp_who2 命令来查看有问题的进程正在做什么。这将显示它是否被另一个进程阻塞,或者使用过多的 cpu 和/或 io 时间。

于 2008-09-09T01:35:47.760 回答
0

我们遇到了同样的问题,这就是我们发现的。

我们的数据库日志大小保持在默认值 (814 MB),自动增长为 10%。在服务器上,最大服务器内存也保持在默认设置 (2147483647 MB​​)。

当我们的日志已满并需要增长时,它使用了服务器的所有内存,并且没有任何东西可以运行代码,所以它超时了。我们最终将数据库日志文件的初始大小设置为 1 MB,将最大服务器内存设置为 2048 MB。这立即解决了我们的问题。当然,您可以更改这两个属性以满足您的需要,但这对于在通过代码执行存储过程时遇到超时问题的人来说是一个想法,但它在 SSMS 中运行速度非常快,并且上述解决方案没有帮助。

于 2013-11-25T18:02:38.530 回答
-1

尝试更改 SelectCommand 超时值:

DataAdapter.SelectCommand.CommandTimeout = 120;
于 2008-08-13T15:52:35.460 回答