Запуск той же хранимой процедуры из приложения C#.Net по сети становится все медленнее с каждое последующее исполнение. Похоже, что это занимает в два раза больше времени, чем предыдущее выполнение (до максимального значения; читайте дальше). Время выполнения становится все медленнее, пока не произойдет 1 из 2 сценариев, после чего первое выполнение SPROC снова становится «быстрым».
SqlConnection
открыт и остается открытым во время всех испытаний, SPROC становится все медленнее, пока не будет запущен любой другой SPROC или запрос .SqlConnection
открывается и закрывается при каждом выполнении, SPROC становится все медленнее, пока не пройдет не менее 8 минут .Это происходит только с несколькими хранимыми процедурами. Один из них — простой SELECT
запрос с 2 JOINs
,(SPROC 1 ), другой — массивный 1600+ строк SPROC(SPROC 2).
Время выполнения никогда не выходит за пределы ровно 60 секунд для SPROC 1 и 67 секунд для SPROC 2 . SPROC 1 первоначально выполняется менее чем за секунду, а SPROC 2 первоначально занимает 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
используемым (и базовым подключением базы данных к источнику данных), поскольку в моем случае включен пул соединений, но почему я наблюдаю это поведение и как его исправить?
Мы используем.Net 2.0 Framework, если это имеет значение.
Выше перечислено много мелких деталей, поэтому, пожалуйста, дайте мне знать, если мне нужно что-то уточнить.
Единственный вопрос о переполнении стека с каким-либо сходством — это этот , но он не имел отношения к моей проблеме.
Изменить: Следующий код выполняется в моем тестовом приложении 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();