Почему хранимой процедуре, которая возвращает таблицу с 9 столбцами и 89 строками с использованием этого кода, требуется 60 секунд для выполнения (.NET 1.1), если для выполнения в SQL Server Management Studio требуется <1 секунды? Он запускается на локальном компьютере, поэтому задержка в сети незначительна / отсутствует, быстрая машина разработчика
Dim command As SqlCommand = New SqlCommand(procName, CreateConnection())
command.CommandType = CommandType.StoredProcedure
command.CommandTimeout = _commandTimeOut
Try
Dim adapter As new SqlDataAdapter(command)
Dim i as Integer
For i=0 to parameters.Length-1
command.Parameters.Add(parameters(i))
Next
adapter.Fill(tableToFill)
adapter.Dispose()
Finally
command.Dispose()
End Try
мой массив параметров набран (для этого SQL это только один параметр)
parameters(0) = New SqlParameter("@UserID", SqlDbType.BigInt, 0, ParameterDirection.Input, True, 19, 0, "", DataRowVersion.Current, userID)
Хранимая процедура - это только оператор выбора, например:
ALTER PROC [dbo].[web_GetMyStuffFool]
(@UserID BIGINT)
AS
SELECT Col1, Col2, Col3, Col3, Col3, Col3, Col3, Col3, Col3
FROM [Table]
У меня была такая же проблема, и я решил ее исправить с помощью этой статьи: databasejournal.com/features/mssql/article.php/3841271/…
Это сработало для меня, поскольку моя хранимая процедура выполняет некоторые ветвления на основе параметров.





Почему бы не сделать его DataReader вместо DataAdapter, похоже, у вас есть единичный набор результатов, и если вы не собираетесь возвращать изменения в БД и вам не нужны ограничения, применяемые в коде .NET, вы не должны использовать Адаптер.
Обновлено:
Если вам нужно, чтобы это был DataTable, вы все равно можете извлекать данные из БД через DataReader, а затем в коде .NET использовать DataReader для заполнения DataTable. Это должно быть быстрее, чем полагаться на DataSet и DataAdapter.
Код, с которым я работаю, не может возвращать ничего, кроме данных для этого sproc.
Я не знаю, «почему» это так медленно само по себе, но, как указывает Маркус, сравнение Mgmt Studio с заполнением набора данных - это яблоки с апельсинами. Наборы данных содержат много накладных расходов. Я их ненавижу и НИКОГДА не использую, если могу.
У вас могут быть проблемы с несоответствием старых версий стека SQL или некоторых подобных (особенно, если вы явно застряли в .NET 1.1). Framework, вероятно, пытается создать базу данных, эквивалентную «отражению», чтобы вывести схему и т. д. И т. Д.
Одна вещь, которую следует рассмотреть, попробовать с вашим досадным ограничением, - это получить доступ к базе данных с помощью устройства чтения данных и создать свой собственный набор данных в коде. Вы сможете легко находить образцы через Google.
и, пожалуйста, используйте некоторые операторы using, поскольку ваше соединение реализует IDisposable
Во-первых, убедитесь, что вы правильно профилируете производительность. Например, дважды запустите запрос из ADO.NET и посмотрите, будет ли второй раз намного быстрее, чем в первый раз. Это устраняет накладные расходы на ожидание компиляции приложения и наращивания инфраструктуры отладки.
Затем проверьте настройки по умолчанию в ADO.NET и SSMS. Например, если вы запустите SET ARITHABORT OFF в SSMS, вы можете обнаружить, что теперь он работает так же медленно, как при использовании ADO.NET.
Однажды я обнаружил, что SET ARITHABORT OFF в SSMS вызвала перекомпиляцию сохраненного процесса и / или использование другой статистики. И внезапно и SSMS, и ADO.NET сообщают примерно одинаковое время выполнения.
Чтобы проверить это, просмотрите планы выполнения для каждого запуска, особенно таблицу syscacheobjects. Наверное, они будут другими.
Запуск sp_recompile для определенной хранимой процедуры удалит связанный план выполнения из кеша, что затем дает SQL Server возможность создать, возможно, более подходящий план при следующем выполнении процедуры.
Наконец, вы можете попробовать подход «сбить его с орбиты» для очистки всего кеша процедур и буферов памяти с помощью SSMS:
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Выполнение этого перед тестированием запроса предотвратит использование кэшированных планов выполнения и кеша предыдущих результатов.
DBCC DROPCLEANBUFFERSDBCC FREEPROCCACHE решил мою проблему. Нужно ли это запускать периодически или только при внесении изменений в хранимую процедуру?
Это на регулярной основе, поскольку это кешированные результаты и планы, которые будут постепенно накапливаться.
Отличный ответ, время выполнения моего SP увеличилось с 117 до 3 с! +1
"ВЫКЛЮЧИТЬ АРИТАБОРТ" был отличным ответом! Теперь у меня есть согласованный опыт между ADO.NET и SSMS. В моем случае мне просто нужно было перестроить один индекс, который я сделал из IDE SSMS.
Да .. DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE решает мою проблему .. но я не хочу очищать кеш для всех объектов в ssms ... могу ли я использовать exec sp_recompile вместо этого для решения этой проблемы. @Дорожный Воин
@Munavvar, извините, опоздал, чтобы увидеть ваш комментарий. Да, sp_recompile очистит кеш плана выполнения для указанной хранимой процедуры.
Вот что я в итоге сделал:
Я выполнил следующий оператор SQL, чтобы перестроить индексы для всех таблиц в базе данных:
EXEC <databasename>..sp_MSforeachtable @command1='DBCC DBREINDEX (''*'')', @replacechar='*'
-- Replace <databasename> with the name of your database
Если я хотел увидеть такое же поведение в SSMS, я запускал процедуру следующим образом:
SET ARITHABORT OFF
EXEC [dbo].[web_GetMyStuffFool] @UserID=1
SET ARITHABORT ON
Другой способ обойти это - добавить это в свой код:
MyConnection.Execute "SET ARITHABORT ON"
Я столкнулся с той же проблемой, но когда я перестроил индексы в таблице SQL, он работал нормально, поэтому вы можете подумать о восстановлении индекса на стороне сервера sql.
Это старый вопрос, и многие его задают. Прежде чем приступить к очистке кеша и поиграться с настройками ARITHABORT, прочтите исчерпывающую статью Эрланда Соммарскога, в которой объясняется, что может происходить: Медленно в приложении, быстро в SSMS? Понимание тайн производительности Довольно часто такое поведение вызвано функцией SQL Server, которая называется «анализ параметров».