代码之家  ›  专栏  ›  技术社区  ›  Eric Z Beard

从Web应用程序查询超时,但从Management Studio运行正常

  •  28
  • Eric Z Beard  · 技术社区  · 16 年前

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

    问题是,Web应用程序中的某个页面在访问存储过程调用时超时,因此使用SQL事件探查器或应用程序跟踪日志查找该查询,并将其粘贴到Management Studio中,以了解其运行缓慢的原因。但你从那里跑出来,它就一直燃烧着,每次不到一秒钟就回来了。

    我的特例是使用ASP.NET 2.0和SQL Server 2005,但我认为这个问题可以应用于任何RDBMS系统。

    8 回复  |  直到 10 年前
        1
  •  27
  •   Bigwave    12 年前

    这是我从研究中学到的。

    .NET发送的连接设置与登录到Management Studio时获得的设置不同。如果您嗅探与SQL事件探查器的连接,将看到以下内容:

    -- 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时运行的每个查询的上方,以确保这些设置是相同的。

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

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

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

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

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

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

    但对于运行频率更高、只需几毫秒就可以尽快返回的其他查询来说,这不是一个选项。

        2
  •  6
  •   Brian Adams    16 年前

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

    您还可以通过分析存储过程来确认这一点。当您从SQL Management Studio执行它时,IO与从ASP.NET应用程序进行配置时的比较情况如何。如果他们很多,它只是重新执行它拉坏的执行计划。

        3
  •  2
  •   Dillie-O    16 年前

    是否已打开ASP.NET跟踪?我有一个实例,问题出在它不是SQL存储过程本身,而是过程返回了5000行,而应用程序正试图用导致问题的5000个项创建数据绑定的列表项。

    您可以通过跟踪查看Web应用程序函数之间的执行时间,以帮助跟踪事件。

        4
  •  1
  •   SQLMenace    16 年前

    首先在临时框中进行测试,然后在SQL Server的服务器级别上进行更改。

    声明@option int

    set@option=@@选项64

    exec sp_配置“用户选项”, @期权

    重新配置

        5
  •  1
  •   Lea Cohen mark winkle    14 年前

    与我在SQL Reporting Services中遇到的问题相同。 尝试检查变量类型, 我向SQL发送不同类型的变量,就像在应该发送varchar的地方发送varchar一样。 是整数,或者类似的东西。 在同步了ReportingService和SQL存储过程中的变量类型之后,我解决了这个问题。

        6
  •  0
  •   GateKiller    16 年前

    尝试更改selectcommand超时值:

    DataAdapter.SelectCommand.CommandTimeout = 120;
    
        7
  •  0
  •   tbreffni    16 年前

    您可以尝试使用sp_who2命令来查看正在执行的进程。这将显示它是否被另一个进程阻塞,或者是否占用了过多的CPU和/或IO时间。

        8
  •  0
  •   Lac Ho    11 年前

    我们也有同样的问题,这就是我们发现的。

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

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