这是我在另一个论坛上提出的问题,该问题得到了一些不错的答案,但我想看看这里是否有人有更多的见解。
问题是,当Web应用程序中的某个页面进入存储过程调用时会超时,因此您使用Sql Profiler或应用程序跟踪日志来查找查询并将其粘贴到管理中工作室,以了解为什么它运行缓慢。但是你从那里开始运行它只是开始,每次不到一秒钟返回。
我的具体案例是使用ASP.NET 2.0和Sql Server 2005,但我认为该问题可能适用于任何RDBMS系统。
答案 0 :(得分:27)
这是我迄今为止从我的研究中学到的东西。
.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从off更改为on将问题查询从90秒减少到1秒。
最可能的解释与参数嗅探有关,这是一种Sql Server用来选择它认为最有效的查询计划的技术。当您更改其中一个连接设置时,查询优化器可能会选择不同的计划,在这种情况下,它显然选择了一个错误的计划。
但我并不完全相信这一点。我尝试在更改此设置后比较实际查询计划,但我还没有看到差异显示任何更改。
arithabort设置还有其他一些可能导致查询在某些情况下运行缓慢的内容吗?
解决方案似乎很简单:只需将set arithabort置于存储过程的顶部即可。但这可能会导致相反的问题:更改查询参数并突然以“关闭”而不是“开启”运行得更快。
暂时我正在运行“重新编译”程序,以确保每次都重新生成计划。对于这个特定的报告来说没关系,因为重新编译可能需要一秒钟,而且报告需要1-10秒才能返回(这是一个怪物)。
但是,对于运行频率更高且需要尽快返回的其他查询,它不是一个选项,只需几毫秒。
答案 1 :(得分:6)
我遇到过类似的问题。尝试在sproc create上设置“WITH RECOMPILE”选项,以强制系统在每次调用时重新计算执行计划。有时,查询处理器会在具有大量分支或案例语句的复杂存储过程中感到困惑,并且只会产生一个非常次优的执行计划。如果这似乎“修复”了问题,您可能需要验证统计信息是否是最新的和/或细分问题。
您还可以通过分析特征来确认这一点。当您从SQL Managment Studio执行它时,IO与从ASP.NET应用程序中分析它时的情况相比如何。如果它们非常多,它只会重新执行它会导致糟糕的执行计划。
答案 2 :(得分:2)
你有没有打开ASP.NET跟踪呢?我有一个实例,其中不是SQL存储过程本身就是问题,事实是该过程返回5000行,并且应用程序试图创建数据绑定ListItems,其中包含导致问题的5000个项目。
您可以通过跟踪来查看Web应用程序功能之间的执行时间,以帮助跟踪事情。
答案 3 :(得分:1)
首先在staging box上测试它,在sql server的服务器级别更改它
宣布@option int
设置@option = @@ options | 64
exec sp_configure'用户选项', @option
RECONFIGURE
答案 4 :(得分:1)
与SQL报告服务相同的问题。 尝试检查变量的类型, 我正在向SQL发送不同类型的变量,比如将varchar发送到应该的位置 是整数,或类似的东西。 在我在Reporting Service和SQL上的存储过程中同步变量类型之后,我解决了这个问题。
答案 5 :(得分:0)
您可以尝试使用sp_who2命令查看有问题的进程正在执行的操作。这将显示它是否被另一个进程阻止,或者使用了过多的cpu和/或io时间。
答案 6 :(得分:0)
我们遇到了同样的问题,这就是我们发现的问题。
我们的数据库日志大小保持默认值(814 MB),自动增长率为10%。 在服务器上,最大服务器内存也保持默认设置(2147483647 MB)。
当我们的日志已满并且需要增长时,它会使用服务器上的所有内存,并且没有任何代码可以运行以便超时。我们最终做的是将数据库日志文件初始大小设置为1 MB,将最大服务器内存设置为2048 MB。这立刻解决了我们的问题。当然,您可以更改这两个属性以满足您的需要,但这是在通过代码执行存储过程时遇到超时问题的人的想法,但它在SSMS中运行得非常快,而上述解决方案无济于事。
答案 7 :(得分:-1)
尝试更改SelectCommand超时值:
DataAdapter.SelectCommand.CommandTimeout = 120;