通过网络运行的从C#的.NET应用程序相同的存储过程与每个随后的执行越来越慢得到。 它似乎采取的时间的两倍的量与先前执行(直到最大值;阅读)。 的执行时间变得越来越慢,直到1 2的情况下发生,在该点处SPROC的第一次执行是“快”一次。
- 如果
SqlConnection
被打开,所有的测试过程中保持开放,该存储过程越来越慢,直到得到任何其他的存储过程或查询运行。 - 如果
SqlConnection
打开,并且每个执行周围闭合,直到至少8分钟已通过SPROC逐渐变得较慢。
这只是和一些存储过程发生。 一个是一个简单的SELECT
查询与2 JOINs
,(SPROC 1)另一个是一个巨大的1600+线SPROC(SPROC 2)。
执行时间似乎永远超越了存储过程正好1 60秒67秒的存储过程2。 SPROC 1花费不到一秒到最初执行,和SPROC 2最初需要7秒。
如果存储过程使用相同的运行这还只是发生SqlConnection
在应用程序中。 只要2个独立SqlConnection
对象被使用时,它们表现为与上述相同的,但是独立的。 上运行存储过程多次SqlConnection1
变得越来越慢,但第一次在同一存储过程是在运行SqlConnection2
,它的“快”。 在多次运行后,它将也变慢SqlConnection2
。
如果应用程序在同一台计算机上与SQL Server 2008 R2安装(运行Windows Server 2008)运行不会出现这种情况。 执行时间始终保持一致。
从Management Studio中运行存储过程还没有得到每次执行速度较慢; 它始终是一致的。
清除的执行计划缓存(SQL Server中)对观察到的行为没有任何影响。
它采取了好几天来缩小这个问题最初是在一个更大的应用观察,以便创建一个测试应用程序能够轻松测试/重现。
从我读过这里 ,有4至8分钟的超时(经过SqlConnection.Close()
被调用的代码),此时将其关闭数据库连接到数据源。 这似乎是符合我上面提到的场景2。
这使我相信它涉及到SqlConnection
在我的情况下启用使用(和底层数据库连接到数据源),因为连接池,但为什么我观察这个行为,我该如何解决?
我们使用的是.NET 2.0框架,如果有什么差别。
有上面列出的很多细节,所以请让我知道,如果我需要澄清什么。
与任何相似之处唯一的堆栈溢出的问题是这样的,但无关我的问题。
编辑:下面的代码在我的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个按钮; 其中一个存储过程调用1如上所述,另调用不具有相同的放缓发出不同的存储过程。 下面的代码是在任一按钮点击(唯一的区别是在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();