Entity Framework 4 Сохраненная процедура Вызов времени - программирование
Подтвердить что ты не робот

Entity Framework 4 Сохраненная процедура Вызов времени

У меня есть хранимая процедура, импортированная в EF4, и когда я вызываю ее с определенными параметрами через 30 секунд, она выдает ошибку тайм-аута. В профилировщике SQL Server я вижу вызов хранимой процедуры с правильными параметрами, занимающими чуть более 30 секунд, что является таймаутом в моем приложении.

ОДНАКО, когда я выполняю тот же SQL, отправленный профилировщику в Query Analyzer, он выполняет подсечку. Что может вызвать это несоответствие между вызовом из EF и вызовом из SQL Server Management Studio?

Полная трассировка стека .NET error ниже.

[SqlException (0x80131904): время ожидания истекло. Период ожидания прошедшее до завершения операции или на сервере, не отвечать на запросы.]
System.Data.SqlClient.SqlConnection.OnError(исключение SqlException, Boolean breakConnection) +2073486
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException исключение, Boolean breakConnection) +5064444
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275
System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
System.Data.SqlClient.SqlDataReader.get_MetaData() +86
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +311
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String метод, результат DbAsyncResult) +162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String метод) +32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior поведение, метод String) +141
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior поведение) +12
System.Data.Common.DbCommand.ExecuteReader(поведение CommandBehavior) +10 System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, поведение CommandBehavior) +443

[EntityCommandExecutionException: ошибка при выполнении определение команды. Подробнее см. Внутреннее исключение.]
System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, поведение CommandBehavior) +479
System.Data.Objects.ObjectContext.CreateFunctionObjectResult(EntityCommand entityCommand, EntitySet entitySet, EdmType edmType, MergeOption mergeOption) +182
System.Data.Objects.ObjectContext.ExecuteFunction(String functionName, Параметры MergeOption mergeOption, ObjectParameter []) +218
System.Data.Objects.ObjectContext.ExecuteFunction(String functionName, Параметры ObjectParameter []) +53
MetaView.DAL.MFCMData.MFCMDATAEntities.GetTradingOpenPositionCounterParty(Nullable 1 positionDT, Nullable 1 tradingAccountID) в C:\Projects\ДЕНЕЖНЫХ\Web\MetaView\MetaView.DAL.MFCMData\MFCMData.Designer.cs: 7064 MetaView.BusinessLayer.Shared.Accounts.CounterParties.GetCounterParties(Int32 tradingAccountID) в C:\Projects\ДЕНЕЖНЫХ\Web\MetaView\MetaView.BusinessLayer\Shared\Accounts\CounterParties.cs: 161

4b9b3361

Ответ 1

Итак, у меня была аналогичная проблема несколько недель назад, которая была объяснена мне одним из наших администраторов баз данных, таким образом (перефразированный и ошарашенный до моего уровня):

При вызове хранимой процедуры SQL Server сервер создает и кэширует план выполнения для каждой хранимой процедуры за object_id. Иногда с помощью SQL Server может быть создан плохой план выполнения, в зависимости от значения параметра, которое передается (в нашем случае это было null для параметра с нулевым значением). Когда это произойдет, быстрое исправление - запустить sp_recompile 'Schema.Procedure' в SQL Server Management Studio (или любой другой инструмент управления базами данных, который вы можете использовать). Все это ясно, что кэш плана для этой хранимой процедуры. Если следующий вызов proc переходит в значение "плохого" параметра снова, вы будете застревать в той же ситуации , чтобы реальное исправление было, чтобы дать подсказку подсказку с использованием синтаксиса OPTIMIZE FOR ( см. http://msdn.microsoft.com/en-gb/library/ms181714.aspx).

Короче, если вы добавите OPTION (OPTIMIZE FOR (@myParameter = 'Some value that gives you a GOOD execution plan')) после предложений WHERE и/или ORDER BY, это должно устранить проблему.

Кроме того, если вам интересно, почему при выполнении одного и того же SQL в SSMS вы всегда получаете быстрые результаты, потому что SSMS имеет значение по умолчанию ON для опции ARITHABORT (SET ARITHABORT ON), которую все остальные приложения установили в OFF по умолчанию, но как это работает, и его последствия не соответствуют моему опыту, и я не удосужился его прочитать. Мне сказали, что я не должен его использовать. Я уверен, что реальный администратор базы данных может лучше объяснить причину.