Web アプリからはクエリがタイムアウトしますが、Management Studio からは正常に実行されます

StackOverflow https://stackoverflow.com/questions/9974

  •  08-06-2019
  •  | 
  •  

質問

これは私が別のフォーラムで質問したもので、まともな回答が得られましたが、ここでより詳しい洞察を持っている人がいるかどうかを確認したかったのです。

問題は、Web アプリケーションのページの 1 つがストアド プロシージャ呼び出しに達したときにタイムアウトになることです。そのため、SQL プロファイラーまたはアプリケーション トレース ログを使用してクエリを見つけ、それを Management Studio に貼り付けて把握します。動作が遅い理由。しかし、そこから実行すると、毎回 1 秒もかからずに戻ってきます。

私の場合は ASP.NET 2.0 と SQL Server 2005 を使用していましたが、この問題はどの RDBMS システムにも当てはまる可能性があると思います。

役に立ちましたか?

解決

これは私がこれまでの研究から学んだことです。

.NET は、Management Studio にログインしたときに取得するものとは異なる接続設定を送信します。SQL Profiler を使用して接続をスニッフィングすると、次のように表示されます。

-- network protocol: TCP/IP  
set quoted_identifier off  
set arithabort off  
set numeric_roundabort off  
set ansi_warnings on  
set ansi_padding on  
set ansi_nulls off  
set concat_null_yields_null on  
set cursor_close_on_commit off  
set implicit_transactions off  
set language us_english  
set dateformat mdy  
set datefirst 7  
set transaction isolation level read committed  

SQLサーバーにログインしたときに実行するすべてのクエリの上にこれらの設定を貼り付けて、設定が同じであることを確認しています。

この場合、切断して再接続した後、各設定を個別に試したところ、arithabort をオフからオンに変更すると、問題のクエリが 90 秒から 1 秒に短縮されることがわかりました。

最も可能性の高い説明は、パラメーター スニッフィングに関連しています。これは、SQL Server が最も効果的なクエリ プランを選択するために使用する手法です。接続設定の 1 つを変更すると、クエリ オプティマイザーは別のプランを選択する可能性がありますが、この場合は明らかに間違ったプランが選択されたようです。

しかし、私はこれに完全に納得しているわけではありません。この設定を変更した後、実際のクエリ プランを比較してみましたが、差分に変更が示されていません。

arithabort の設定に関して、場合によってはクエリの実行が遅くなる可能性があるものは他にありますか?

解決策は簡単そうに見えました。set arithabort をストアド プロシージャの先頭に置くだけです。しかし、これは次のような逆の問題を引き起こす可能性があります。クエリパラメータを変更すると、突然「オン」よりも「オフ」の方が速く実行されます。

当面は、計画が毎回確実に再生成されるように「再コンパイルあり」の手順を実行しています。この特定のレポートでは問題ありません。再コンパイルにおそらく 1 秒かかるため、返されるまでに 1 ~ 10 秒かかるレポートではこれはあまり目立ちません (これはモンスターです)。

ただし、より頻繁に実行され、できるだけ早く (わずか数ミリ秒で) 返す必要がある他のクエリの場合は、これはオプションではありません。

他のヒント

私も同様の問題を抱えていました。sproc create で with "WITH RECOMPILE" オプションを設定して、呼び出されるたびにシステムに実行計画を強制的に再計算させてみてください。場合によっては、クエリ プロセッサが、多くの分岐や case ステートメントを含む複雑なストアド プロシージャで混乱し、実際には次善の実行プランを実行してしまうことがあります。これで問題が「解決」したように見える場合は、統計が最新であることを確認するか、sproc を分析するか、あるいはその両方が必要になるでしょう。

sproc をプロファイリングすることでこれを確認することもできます。SQL Management Studio から実行した場合の IO は、ASP.NET アプリケーションからプロファイリングした場合と比較してどうなるでしょうか。あまりにも多い場合は、間違った実行計画を立てていることが改めて強調されるだけです。

ASP.NET トレースをもう有効にしましたか?SQL ストアド プロシージャ自体が問題ではなく、プロシージャが 5000 行を返し、アプリがそれらの 5000 項目を含むデータバインドされた ListItem を作成しようとしたことが問題の原因だったというインスタンスがありました。

状況を追跡するために、トレースを通じて Web アプリ関数間の実行時間を調べることもできます。

まずステージング ボックスでこれをテストし、SQL サーバーのサーバー レベルで変更します。

@option int を宣言する

@option = @@ optionsを設定| 64

exec sp_configure 'ユーザーオプション'、@option

再構成

SQL レポート サービスでも同じ問題がありました。変数のタイプを確認してみてください。SQLに異なるタイプの変数を送信していました。varcharを整数にする必要がある場合、またはそのようなものを配置しました。Reporting Service と SQL のストアド プロシージャの変数の型を同期した後、問題は解決しました。

sp_who2 コマンドを使用して、問題のプロセスがどのような動作をしているかを確認してみてください。これにより、別のプロセスによってブロックされているかどうか、または過度の CPU 時間や IO 時間を使用しているかどうかがわかります。

私たちも同じ問題を抱えていて、そこでわかったことを以下に示します。

データベースのログ サイズはデフォルト (814 MB) に維持され、自動増加は 10% でした。サーバーでは、最大サーバー メモリもデフォルト設定 (2147483647 MB​​) に維持されました。

ログがいっぱいになって拡大する必要があると、サーバーのメモリがすべて使用され、コードを実行するためのものが何も残らないため、タイムアウトになってしまいました。最終的には、データベース ログ ファイルの初期サイズを 1 MB に、最大サーバー メモリを 2048 MB に設定しました。これで問題は即座に解決されました。もちろん、ニーズに合わせてこれら 2 つのプロパティを変更できますが、これは、コード経由でストアド プロシージャを実行するときにタイムアウトの問題が発生する人のためのアイデアですが、SSMS では非常に高速に実行され、上記の解決策は役に立ちません。

SelectCommand のタイムアウト値を変更してみてください。

DataAdapter.SelectCommand.CommandTimeout = 120;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top