关于sql:查询从Web应用程序超时,但在Management Studio中运行良好

关于sql:查询从Web应用程序超时,但在Management Studio中运行良好

Query times out from web app but runs fine from management studio

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

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

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


到目前为止,这是我从研究中学到的。

.NET发送的连接设置与登录Management Studio时得到的设置不同。如果您嗅探与Sql Profiler的连接,则将看到以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 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秒才能返回的报告来说,这并不是太明显(这是一个怪兽)。

但这不是其他查询的选择,这些查询运行频率更高,并且需要在几毫秒内尽快返回。


我也遇到过类似的问题。尝试在sproc create上设置" WITH RECOMPILE"选项,以强制系统在每次调用时重新计算执行计划。有时,查询处理器会在带有许多分支或case语句的复杂存储过程中感到困惑,而只是提出一个真正次优的执行计划。如果这似乎可以"解决"问题,则可能需要验证统计信息是否最新和/或分解存储过程。

您还可以通过分析存储过程来确认这一点。当您从SQL Managment Studio执行它时,IO与从ASP.NET应用程序对其进行概要分析时相比如何。如果他们很多的话,那只会强化它制定了糟糕的执行计划。


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

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


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


首先在暂存盒中进行测试,然后在SQL Server的服务器级别上对其进行更改

declare @option int

set @option = @@options | 64

exec sp_configure 'user options',
@option

RECONFIGURE


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

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

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


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


尝试更改SelectCommand超时值:

1
DataAdapter.SelectCommand.CommandTimeout = 120;


推荐阅读