从ASP.NET与SQL管理管理员调用时,存储过程较慢

时间:2013-06-28 12:12:27

标签: c# sql-server performance

我们正在尝试诊断复杂存储过程的缓慢(它有几个巨大的查询)。

当我们从ASP.NET调用SP时,需要5秒钟。

当我们从SQL Management Studio(仅使用EXEC)调用它时,需要0.05秒。

我们已经在许多不同的方式和环境中持续测试了这种行为。

这是使用C#.NET。该数据库是MS SQL Server 2012。

问题在于网络应用程序,但我们编写了一个小型控制台应用程序作为测试工具,行为是相同的。

1)我们在C#.NET控制台应用程序中计算经过的时间,如下所示:

stopwatch.Start();
rdr = cmd.ExecuteReader();
stopwatch.Stop();

2)我们通过在查询之前和之后调用GETDATE()来计算SQL过程中的经过时间,然后将这些时间存储在一个小表中。我们可以在SQL Mgmt Studio中查询该表,以查看SP内部的查询所花费的时间。

通过这种方式,我们可以看到SQL与整体花费了多少时间,其中99%用于SQL。

但如果SQL Mgmt Studio中的速度也不慢,则很难调试和改进。

所以我的问题是,为什么差异?可能是SQL Mgmt Studio的锁定方式与控制台应用程序不同吗?

2 个答案:

答案 0 :(得分:10)

这种行为通常源于您从ADO.NET和SSMS获得不同的执行计划。这是因为执行计划不仅要考虑SQL本身,还要考虑ANSI_NULLS,ARITHABORT和其他几种设置形式的上下文。因此,如果这些设置不相同,则不能在另一个环境中使用执行计划。

使用默认设置,SSMS和ADO.NET中的所有内容都相同,但ARITHABORT除外。这在ADO.NET中设置为OFF,在SSMS中设置为ON,因此要获得与应用程序相同的缓存查询计划,需要在SSMS中设置ARITHABORT OFF。现在,您应该在SSMS中看到与应用程序调用中相同的性能。在这篇精彩的博文中查看更多背景信息:http://www.sommarskog.se/query-plan-mysteries.html

如果您的查询返回大量数据,则还有另一个因素,因为每个默认SSMS读取所有数据并在完成之前显示它并显示总查询时间。读取速度取决于您在服务器或远程本地执行SSMS的位置。在远程的情况下,数据必须通过网络传输,这通常比本地呼叫慢。通常,测量传输时间是可以的,因为您的应用程序也是如此。但是,SSMS还显示数据,这可能比实际加载数据花费更长的时间。为了防止这种情况,您可以通过“工具 - >选项 - >查询结果 - > SQL Server->结果到网格 - >执行后丢弃SSMS中的数据显示”。

如果仍然有不同的行为,请通过SQL事件探查器捕获执行计划并进行比较。

答案 1 :(得分:6)

去年我有类似的问题。尝试在存储过程中启用arithabort:SET ARITHABORT ON

摘自msdn

  

SQL Server Management Studio的默认ARITHABORT设置为ON。将ARITHABORT设置为OFF的客户端应用程序可以接收不同的查询计划,从而难以对执行不佳的查询进行故障排除。 也就是说,相同的查询可以在管理工作室中快速执行,但在应用程序中速度较慢。使用Management Studio进行疑难解答时,始终与客户端ARITHABORT设置匹配。