7

LinqToSQLを使用して呼び出しているストアドプロシージャがあります。私は特別なことは何もしていません。

MyDataContext db = new MyDataContext()

var results = db.storedProcedure(param1, param2, param3)

// Do stuff

まったく同じパラメータを使用してストアドプロシージャを実行すると、2〜6秒の結果が得られます。データベースはリモートデータベースです。

ただし、ストアドプロシージャを実行すると、(デバッグ後....)275秒かかります。通常の状況では、これにより次の例外が発生します。

[Win32Exception(0x80004005):待機操作がタイムアウトしました]

[SqlException(0x80131904):タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。] System.Data.SqlClient.SqlConnection.OnError(SqlException例外、ブール値breakConnection、アクション1 wrapCloseInAction) +1753346 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)+5295154 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj、Boolean callerHasConnectionLock、Boolean asyncClose)+242 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior、SqlCommand cmdHandler、SqlDataReader 、Boolean&dataReady)+1682 System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()+59 System.Data.SqlClient.SqlDataReader.get_MetaData()+90 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior runBehavior、String resetOptionsString )+365 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、Boolean async、Int32 timeout、Task&task、Boolean asyncWrite)+1325 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、String method、TaskCompletionSource`1 complete、Int32 timeout、Task&task、Boolean asyncWrite)+175 System.Data.SqlClient.SqlCommand .RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、String method)+53 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior Behavior、String method)+134 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior Behavior)+41 System.Data.Common.DbCommand.ExecuteReader()+12 System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query、QueryInfo queryInfo、IObjectReaderFactory factory、Object [] parentArgs、Object [] userArgs、ICompiledSubQuery [] subQueries、Object lastResult)+1306 System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query、QueryInfo [] queryInfos、IObjectReaderFactory factory、Object [] userArguments、ICompiledSubQuery [] subQueries)+118System.Data.Linq.SqlClient.SqlProvider。 System.Data.Linq.Provider.IProvider.Execute(Expression query)+342 System.Data.Linq.DataContext.ExecuteMethodCall(Object instance、MethodInfo methodInfo、Object [] parameters)+83Object []パラメータ)+83Object []パラメータ)+83

他のすべてのストアドプロシージャは同じ方法で呼び出されますが、この問題が発生するものはありません。リモートDB管理者は、タイムアウトが発生する前に呼び出しの開始と終了を確認できると言っているため、Linqがデータを受信した後の手順と関係があるようです。

誰かがこれを以前に経験したことがあり、それを修正する方法について何かアイデアはありますか?

dmblファイルからSPを削除して、再度追加してみました。値の1つが10進数から2進数に変更されていることに気づきましたが、それ以外はすべて同じです。

いつものように、昨日はうまくいっていました!

前もって感謝します。

4

2 に答える 2

4

わかりました、私はついにこの問題に対する本当の答えを発見しました。SSMS は通常、ARITHABORT ON を使用し、コードは通常 ARITHABORT OFF を使用します。これは基本的に、コード内の数学行にエラーがある場合 (ゼロ除算など) の処理方法のオプションです。

ただし、ここで重要なことは、両方の方法の実行計画が異なるということです。そのため、Web サイトでは SSMS よりも同じ処理に (ランダムに) 時間がかかることがあります。

実行計画は、最初に使用されたときの見積もりに基づいてコンパイルされるため、最初のクエリには適しているが、後続のクエリではひどい方法で実行計画がキャッシュされていることがランダムにわかります。これがここで起こったことであり、ストアド プロシージャが変更された後に新しいクエリ プランが作成され、突然再び機能し始めた理由でもあります。

最後に、ストアド プロシージャで WITH RECOMPILE を使用したため、実行計画を効率的に再利用することはできませんでしたが、違いに気付かず、それ以来問題は発生していません。

于 2013-07-18T15:04:53.407 に答える
0

この問題の原因は、Linq.Table< >.Count() に依存するループでした。開発環境では、基になるクエリはほぼ瞬時に実行されますが、本番環境では数秒かかりました。SQL プロファイラーを接続すると、ループの反復ごとにクエリが実行されることが明らかになったため、これらの「数秒」が加算され始め、最終的にタイムアウトになりました。

私にとっての解決策は、Count() の結果をローカル変数に割り当て、それをループで使用して、Count() が反復ごとにクエリを再実行しないようにすることでした。遅いクエリを再実行する組み込みの Linq 集計関数に依存している場合、他の人がこの問題を経験すると思います。

于 2013-03-03T18:10:04.647 に答える