7

ネットワーク上でC#.Netアプリケーションから同じストアドプロシージャを実行すると、その後の実行ごとに徐々に遅くなります。前回の実行の2倍の時間がかかるようです(最大値まで、読み進めてください)。2つのシナリオのうちの1つが発生するまで、実行時間は徐々に遅くなります。その時点で、SPROCの最初の実行は再び「高速」になります。

  1. SqlConnectionが開かれ、すべてのテスト中に開いたままになると、他のSPROCまたはクエリが実行されるまで、SPROCの速度が徐々に低下ます
  2. 各実行の前後でを開いたり閉じたりするSqlConnectionと、SPROCは少なくとも8分が経過するまで徐々に遅くなります。

これは、いくつかのストアドプロシージャでのみ発生します。1つは2を使用した単純なSELECTクエリJOINsSPROC 1)、もう1つは1600行以上の大規模なSPROC(SPROC 2)です。

実行時間は、SPROC 1では正確に60秒、SPROC2では67秒を超えることはないようです。SPROC 1の最初の実行には1秒もかからず、 SPROC2の最初の実行には7秒かかります。

これは、SPROCがアプリケーションで同じものを使用して実行されている場合にのみ発生SqlConnectionします。2つの別々のオブジェクトが使用されるとすぐにSqlConnection、それらは上記と同じように動作しますが、独立しています。でSPROCを複数回実行するSqlConnection1と、徐々に遅くなりますが、同じSPROCを初めて実行するときはSqlConnection2、「高速」です。で複数回実行すると、速度も低下しますSqlConnection2

これは、SQL Server 2008 R2がインストールされている(Windows Server 2008を実行している)同じコンピューターでアプリケーションを実行している場合は発生しません。実行時間は常に一定です。

Management Studio内からのストアドプロシージャの実行も、実行のたびに遅くなることはありません。それは常に一貫しています。

(SQL Serverで)実行プランキャッシュをクリアしても、監視される動作には影響しません。

テストアプリを作成して簡単にテスト/再現できるようにするために、はるかに大きなアプリケーションで最初に観察されたこの問題を絞り込むのにかなりの日数がかかりました。

私がここで読んだことから、4〜8分のタイムアウトがあり(SqlConnection.Close()コードで呼び出された後)、その時点でデータソースへのデータベース接続が閉じられます。これは、前述のシナリオ2と一致しているようです。

これによりSqlConnection、私の場合は接続プールが有効になっているため、使用済み(およびデータソースへの基になるデータベース接続)に関連していると思いますが、なぜこの動作を観察し、どのように修正すればよいですか?

違いがあれば、.Net2.0Frameworkを使用しています。

上記の詳細はたくさんありますので、何か明確にする必要がある場合はお知らせください。

類似点がある唯一のStackOverflowの質問はこれですが、私の問題とは無関係でした。

編集: 次のコードは、起動時に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つは上記のSPROC1を呼び出し、もう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();
4

1 に答える 1

3

この問題をデバッグするための私のアイデアは次のとおりです。

  • 接続を破棄した後、SqlConnection.ClearAllPools()を呼び出してみてください。これで問題が解決した場合、問題は確実に特定の接続に関連付けられています。
  • 次に、SPROCを明示的なトランザクションで囲みます。
  • 次に、SPROCを呼び出す前に、SqlConnection.ClearAllPools()を呼び出します。
  • SPROCはどのくらいのデータを返しますか?
  • 接続を開いてSPROCを実行するために使用しているC#コードを投稿してください。
  • 表示されている動作を再現するスタンドアロンのコンソールアプリを作成します。これは(おそらく)コンソールアプリが正常に実行されるため、アプリの何かに問題があることを証明します。
于 2012-04-11T20:31:41.990 に答える