ネットワーク上でC#.Netアプリケーションから同じストアドプロシージャを実行すると、その後の実行ごとに徐々に遅くなります。前回の実行の2倍の時間がかかるようです(最大値まで、読み進めてください)。2つのシナリオのうちの1つが発生するまで、実行時間は徐々に遅くなります。その時点で、SPROCの最初の実行は再び「高速」になります。
SqlConnection
が開かれ、すべてのテスト中に開いたままになると、他のSPROCまたはクエリが実行されるまで、SPROCの速度が徐々に低下します。- 各実行の前後でを開いたり閉じたりする
SqlConnection
と、SPROCは少なくとも8分が経過するまで徐々に遅くなります。
これは、いくつかのストアドプロシージャでのみ発生します。1つは2を使用した単純なSELECT
クエリJOINs
(SPROC 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();