执行时间随同一个SPROC的每次迭代而变慢
通过网络从C#.Net应用程序运行相同的存储过程随着每次后续执行逐渐变慢。 它看起来要比前一次执行时间缩短两倍 (达到最大值;请继续阅读)。 执行时间逐渐变慢,直到发生两种情况中的一种,此时SPROC的第一次执行又是“快速”。
SqlConnection
在所有测试期间打开并保持打开状态,则SPROC会逐渐变慢,直到运行其他 SPROC 或查询为止。 SqlConnection
,则SPROC将逐渐变慢,直到至少8分钟过去。 这只会在少数存储过程中发生。 一个是带有2个JOINs
的简单SELECT
查询,(SPROC 1)另一个是1600+行SPROC(SPROC 2)。
SPROC 1的执行时间似乎永远不会超过60秒,SPROC 2的执行时间也不会超过60秒。SPROC 1的初始执行时间不到1秒,SPROC 2最初需要7秒。
这也仅在SPROC在应用程序中使用相同的SqlConnection
运行时才会发生。 只要使用了2个单独的SqlConnection
对象,它们的行为与上述相同,但是是独立的。 在SqlConnection1
多次运行SPROC会逐渐变慢,但是第一次在SqlConnection2
上运行同一个SPROC时,它是“快速”的。 在SqlConnection2
多次运行时,它也会变慢。
如果应用程序在安装了SQL Server 2008 R2的计算机上运行(运行Windows Server 2008),则不会发生这种情况。 执行时间始终一致。
在Management Studio中运行存储过程在每次执行时都不会变慢; 它总是一致的。
清除执行计划缓存(在SQL Server中)对观察到的行为没有影响。
为了创建一个测试应用程序来轻松测试/复制它,已经花了不少时间来缩小最初在更大的应用程序中观察到的这个问题。
从我在这里读到的,有4到8分钟的时间(在代码中调用SqlConnection.Close()
之后),此时它关闭了与数据源的数据库连接。 这似乎与我上面提到的情景2一致。
这导致我相信它与使用的SqlConnection
(以及与数据源的底层数据库连接)有关,因为在我的情况下启用了连接池,但是为什么我会观察此行为,以及如何解决此问题?
如果这有什么不同,我们正在使用.Net 2.0框架。
上面列出了许多优良的细节,所以请让我知道是否需要澄清任何事情。
唯一有任何相似之处的Stack Overflow问题是这样的,但与我的问题无关。
编辑:以下代码在启动时在我的WinForms测试应用程序中执行:
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder();
connectionStringBuilder.DataSource = m_DataSource;
connectionStringBuilder.InitialCatalog = m_InitialCatalog;
connectionStringBuilder.UserID = m_UserID;
connectionStringBuilder.Password = m_Password;
connectionStringBuilder.IntegratedSecurity = false;
connectionString = connectionStringBuilder.ConnectionString;
m_DatabaseConnection = new SqlConnection(connectionString);
然后我有2个按钮; 其中一个调用上面提到的SPROC 1,另一个调用不同的SPROC,它不具有相同的放缓问题。 下面的代码在任意一个按钮上执行(只有SPROC名称不同):
m_DatabaseConnection.Open();
m_DatabaseCommand = new SqlCommand("GetCompanies", m_DatabaseConnection);
m_DatabaseCommand.Parameters.AddWithValue("@StatusID", StatusID);
m_DatabaseCommand.CommandType = CommandType.StoredProcedure;
m_DatabaseCommand.CommandTimeout = 0;
SqlDataAdapter databaseDataAdapter = new SqlDataAdapter(m_DatabaseCommand);
DataSet databaseDataSet = new DataSet();
databaseDataAdapter.Fill(databaseDataSet);
m_DatabaseConnection.Close();
这里是我的想法来调试这个问题:
上一篇: Execution Time Slower with each Iteration of the same SPROC