在网络上从C#.Net应用程序运行相同的存储过程随着每次后续执行而逐渐变慢。与上一次执行相比,花费的时间似乎是的时间的两倍(最大值;请继续阅读)。执行时间逐渐变慢,直到发生2个场景中的1个,此时SPROC的第一次执行再次“快速”。

  • 如果在所有测试过程中打开了SqlConnection并保持打开状态,
    SPROC会逐渐变慢,直到运行任何其他 SPROC 或查询
  • 如果每次执行都打开和关闭SqlConnection,则
    SPROC会逐渐变慢,直到至少经过了8分钟

  • 这仅在少数存储过程中发生。一个是带有2个SELECT(SPROC 1)的简单JOINs查询,另一个是庞大的1600+行SPROC(SPROC 2)。

    SPROC 1的执行时间似乎永远不会超过60秒,SPROC 2的执行时间永远不会超过67秒。SPROC1最初花费的时间不到一秒钟,而SPROC 2最初花费的时间为7秒。

    仅当在应用程序中使用相同的SqlConnection运行SPROC时,才会发生这种情况。一旦使用了2个单独的SqlConnection对象,它们的行为与上述相同,但是是独立的。在SqlConnection1上多次运行SPROC会逐渐变慢,但是第一次在SqlConnection2上运行相同的SPROC却是“快速”。当在SqlConnection2上多次运行时,它也会变慢。

    如果应用程序在装有SQL Server 2008 R2的同一台计算机上运行(运行Windows Server 2008),则不会发生这种情况。执行时间始终是一致的。

    从Management Studio中运行存储过程也不会随着每次执行而变慢。它始终是一致的。

    清除执行计划缓存(在SQL Server中)对观察到的行为没有影响。

    为了创建一个易于测试/复制它的测试应用程序,花了好几天的时间来缩小最初在更大的应用程序中观察到的问题。

    从我读过here的内容来看,有4到8分钟的超时(在代码中调用SqlConnection.Close()之后),此时超时将关闭数据库与数据源的连接。这似乎与我上面提到的方案2一致。

    这使我相信它与所使用的SqlConnection(以及与数据源的基础数据库连接)有关,因为在我的情况下启用了连接池,但是为什么我观察到此行为,以及如何解决此问题?

    如果有任何不同,我们将使用.Net 2.0 Framework。

    上面列出了许多详细信息,因此,如果我需要澄清任何内容,请告诉我。

    唯一具有相似性的堆栈溢出问题是this,但与我的问题无关。

    编辑:
    以下代码在启动时在我的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();
    

    最佳答案

    这是我调试此问题的想法:

  • 处置连接后,尝试调用SqlConnection.ClearAllPools()。如果这样可以解决问题,则可以肯定地将问题与特定的连接相关联。
  • 接下来,将SPROC包含在显式事务中。
  • 接下来,在调用SPROC之前调用SqlConnection.ClearAllPools()。
  • SPROC返回多少数据?
  • 请发布您用于打开连接并执行SPROC的C#代码。
  • 创建一个独立的控制台应用程序,该应用程序将重现您所看到的行为。这将(有可能)证明您的应用程序中存在某些问题,因为控制台应用程序可以正常运行。
  • 关于c# - 每个SPROC迭代的执行时间变慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10113255/

    10-12 21:55