Проблемы с производительностью хранимой процедуры — слишком медленное закрытие соединения

Ранее я задавал вопрос о хранимой процедуре, которая также выполнялась медленно на сервере sql, однако, если я запустил sproc в Query Analyzer, он вернется менее чем за одну секунду. Клиент представляет собой приложение winforms .NET 1.1.

Я смог подключиться через VNC к ящику пользователя, и, конечно же, у них не было установленных инструментов SQL, поэтому я запустил Excel, зашел в VBA и написал быструю функцию для вызова sproc с точно такими же параметрами.

Оказывается, sproc возвращает долю секунды, и я могу перебрать все строки в кратчайшие сроки. Однако закрытие соединения занимает очень много времени, от 5 до 30 секунд.

Почему закрытие соединения занимает так много времени?


person AngryHacker    schedule 09.04.2009    source источник
comment
Мы нашли проблему. Кэш чтения/записи в RAID-массиве был отключен местным ИТ-специалистом из-за разрядившейся батареи. Не спрашивайте меня, почему RAID-массив работает от батареи.   -  person AngryHacker    schedule 11.04.2009
comment
Батарея используется для сохранения кэша RAID-контроллера в памяти. Таким образом, если питание отключается во время записи, RAID-контроллер сохраняет данные, которые необходимо записать на диск, тем самым сохраняя ваши массивы в безопасности. Когда эта батарея садится, кэширование отключается.   -  person Brent Ozar    schedule 14.04.2009


Ответы (3)


Описанные вами симптомы почти всегда связаны с «неправильным» кэшированным планом запроса. Хотя это большая тема (см. обнюхивание параметров здесь, на SO) , часто (но не всегда) можно решить проблему, перестроив индексы базы данных и убедившись, что вся статистика актуальна.

person Mitch Wheat    schedule 10.04.2009
comment
Я устранил сниффинг параметров как возможную причину. Это не так. Я также перестроил индексы и сделал полное обновление статистики с помощью полного сканирования. Обратите внимание, что данные возвращаются быстро. Соединение закрывается навсегда. - person AngryHacker; 10.04.2009
comment
@AngryHacker: когда вы говорите «закрыть соединение», вы имеете в виду, что оно возвращается в пул соединений? Можете ли вы опубликовать пример кода, который дает такое поведение? - person Mitch Wheat; 10.04.2009
comment
Проблема решена (см. мой комментарий к OQ). Тем не менее, я узнал, что когда вы закрываете соединение (conn.Close) , но не выполняете цикл по строкам, метод фактически передаст все строки клиенту, прежде чем фактически закрыть соединение. - person AngryHacker; 11.04.2009

Если вы используете SqlDataReader, вы можете попробовать, когда у вас есть все необходимые данные, вызвать Cancel в SqlCommand перед вызовом Close в SqkDataReader. Это предотвратит заполнение выходных параметров и возвращаемых значений, что может быть причиной медленного закрытия соединения. Сделайте это в блоке try catch, потому что он может вызвать исключение, отмененное пользователем.

person JP Alioto    schedule 10.04.2009

Объединение соединений?

Это, или я бы проверил наличие каких-либо пакетов обновлений или статей базы знаний для клиентской библиотеки.

person Michael K. Campbell    schedule 10.04.2009