17

ストアド プロシージャを EF4 にインポートしましたが、30 秒後に特定のパラメーターを指定して呼び出すと、タイムアウト エラーがスローされます。SQL Server プロファイラーでは、アプリケーションのタイムアウトである 30 秒強かかる適切なパラメーターを使用したスト​​アド プロシージャ コールを確認できます。

ただし、Query Analyzer でプロファイラーに送信された同じ SQL を実行すると、1 秒未満で実行されます。EF からの呼び出しと SQL Server Management Studio からの呼び出しとの間で、この不一致が生じる原因は何ですか?

以下の .NET エラーの完全なスタック トレース。

[SqlException (0x80131904): タイムアウトが発生しました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していませ ん

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、文字列 resetOptionsString) +311
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、ブール値 returnStream、ブール値 async) +987
System.Data.SqlClient .SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
System.Data. SqlClient.SqlCommand.ExecuteReader(CommandBehavior 動作、文字列メソッド) +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 behavior) +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(Nullable1 positionDT, NullableC:\Projects\CASH\web\MetaView\MetaView.DAL.MFCMData\MFCMData.Designer.cs:7064 内の 1 TradingAccountID) MetaView.BusinessLayer.Shared.Accounts.CounterParties.GetCounterParties(Int32 TradingAccountID) C:\Projects\CASH 内\web\MetaView\MetaView.BusinessLayer\Shared\Accounts\CounterParties.cs:161

4

1 に答える 1

24

それで、私は数週間前に同様の問題を抱えていました。これは、DBAの1人から次のように説明されました(もちろん、言い換えて、私のレベルに合わせて唖然としました):

SQL Server ストアド プロシージャが呼び出されると、サーバーはストアド プロシージャごとobject_idに実行計画を作成してキャッシュします。渡されたパラメーター値によっては、SQL Server によって不適切な実行プランが作成されることがあります (この例では、null 許容パラメーターに対して null でした)。これが発生した場合の簡単な解決策はsp_recompile 'Schema.Procedure'、SQL Server Management Studio (または使用している DB 管理ツール) で実行することです。これは、そのストアド プロシージャのプラン キャッシュをクリアするだけです。proc の次の呼び出し先が再び「不正な」パラメータ値を渡すと、同じ状況に陥ってしまうため、実際の修正はOPTIMIZE FOR、構文を使用してクエリにヒントを与えることです ( http://msdn.microsoft.comを参照)。 /en-gb/library/ms181714.aspx )。

つまり、 and/or句OPTION (OPTIMIZE FOR (@myParameter = 'Some value that gives you a GOOD execution plan'))の後に追加すると、問題が解決するはずです。WHEREORDER BY

また、SSMS で同じSQL を実行すると常に高速な結果が得られるのはなぜかというと、SSMS には ARITHABORT ( SET ARITHABORT ON) というオプションのデフォルト設定が ON に設定されているためです。他のすべてのアプリではデフォルトで OFF に設定されていますが、どのように作品とその意味は私の経験を超えており、私はそれを読むことを気にしていません. 使ってはいけないと言われましたが。本物の DBA なら、その理由をもっとうまく説明できるはずです。

于 2013-04-02T20:00:09.737 に答える