SqlDataAdapter.Fill () Тайм-аут - базовый Sproc быстро возвращается - PullRequest
4 голосов
/ 20 апреля 2009

У меня есть SqlDataAdapter, который заполняется 21 строкой данных (4 столбца). Sproc, который управляет им, возвращается через пару секунд в SQL Mgmt Studio, но .Fill () занимает 5 минут.

    ArrayList ret = new ArrayList();
    SqlDataAdapter da = null;
    SqlCommand cmd = null;  
        cmd = base.GetStoredProc("usp_dsp_Stuff"); //Returns immediately in MSSMS.
        cmd.CommandTimeout = 3600; // Set to 6 min - debug only
        base.AddParameter(ref cmd, "@Param1", ParameterDirection.Input, SqlDbType.BigInt, 8, 19, 0, theParam1);
        base.AddParameter(ref cmd, "@Param2", ParameterDirection.Input, SqlDbType.BigInt, 8, 19, 0, theParam2);
        base.AddParameter(ref cmd, "@Param3", ParameterDirection.Input, SqlDbType.Char, 1, 'C');
        da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt); //Takes 5 minutes.

Есть идеи?

Заранее спасибо! -Крис

Ответы [ 7 ]

3 голосов
/ 17 февраля 2017

Я знаю, что уже слишком поздно, как и на 7 лет позже! но я столкнулся с этой проблемой сегодня и хотел поделиться своим решением. В моем случае данные, извлеченные из SQL, представляли собой табличную функцию. Функция с табличными значениями возвратила только около 3500 строк и заняла менее 1 секунды, но по тайм-ауту воспользовалась функцией Fill () в коде c #. Я не знаю, кто или как это работает, но удаление и повторное создание функции исправили это. Я думаю, что это как-то связано с тем, как .NET читает данные, предоставляемые SQL, например, способ, которым необходимо воссоздать представление, если вы вносите в него изменения после того, как оно используется в отчете. Опять же, я не уверен на 100%, что происходит за кулисами, но для меня это было быстрое решение

2 голосов
/ 17 июля 2018

Недавно я испытал именно это: .Fill истекло время ожидания, но тот же SP был сверхбыстрым в SQL Server Management Studio. Это связано с тем, что ваше приложение .NET создает соединение SQL и использует SET ARITHABORT OFF, тогда как SQL Server Management Studio по умолчанию использует SET ARITHABORT ON. Это приводит к использованию двух разных планов выполнения, поэтому вы не смогли воспроизвести это время ожидания в SQL Server Management Studio. Я рекомендую вам взглянуть на ваш SP и внести некоторые изменения.

2 голосов
/ 03 августа 2017
da = new SqlDataAdapter(cmd);
da.SelectCommand.CommandTimeout = 1800;
2 голосов
/ 20 апреля 2009

Спасибо за помощь. Решением этой проблемы было добавить операторы (nolock) для объединений, которые использовал sproc:

ИЗ category_tbl c ВНУТРЕННИМ СОЕДИНЕНИЕМ dbo.categoryItem_LNK cl С (NOLOCK) ВКЛ

Я не знаю, почему мы видели только ухудшение качества при использовании SqlDataAdapter, но это изменило, и это решило проблему сразу.

Еще раз спасибо, Chris

1 голос
/ 03 февраля 2010

Плохие планы запросов и сниффинг параметров. Для хранимой процедуры, и особенно той, где параметры будут дико корректировать прочитанные строки, причиной является плохой план выполнения из-за просмотра входящих параметров. Это не происходит в SQL Management Studio из-за различных параметров SET.

Эта ветка прекрасно подводит итог вашей проблемы: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/9fd72536-f714-422a-b4c9-078e2ef365da/

Это типичный случай параметра нюхают. Ваше приложение скорее всего работает с различными параметрами SET (установлено клиентским API) и использует другой план выполнения, чем тот создан в SSMS. Что происходит, когда ваша процедура вызывает первый время через ваше приложение создает план выполнения на основе параметров прошло. Тем не менее, этот план выполнения не может быть хорошим для другого набора параметр, который может привести к плохой производительность при исполнении с другой набор параметров. Увидеть следующие для более подробной информации и разные решения: http://pratchev.blogspot.com/2007/08/parameter-sniffing.html

Подробнее о внутреннем кэшировании плана и повторном использовании плана запроса:
http://technet.microsoft.com/en-us/library/cc966425.aspx

1 голос
/ 22 апреля 2009

Я не хочу выпускать новости, но (NOLOCK) не является решением, оно просто создает новые проблемы , такие как грязное чтение, отсутствующие / дублированные данные и даже прерванные запросы. Блокировки в базе данных SQL - ваш друг.

Если блокировка (или, что еще хуже, блокировка) вызывала медленную работу, вы сравниваете параметры подключения, работающие через SSMS, и параметры, используемые вашим приложением. Используйте SQL Profiler, чтобы увидеть, как выполняется код.

Если какое-либо из этих полей является крупным объектом, имейте в виду, что SSMS автоматически получает только несколько сотен символов по умолчанию. Возвращенные дополнительные данные могут быть фактором.

0 голосов
/ 20 апреля 2009

Fill () иногда может быть медленным, потому что .NET анализирует данные, которые возвращаются из процедуры.

Используйте SQL Profiler для определения того, что SQL .NET фактически отправляет при выполнении Fill ().

Если он отправляет много операторов SET, например

set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off

etc...

.. затем добавление тех же самых операторов set в вашу хранимую процедуру может ускорить процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...