Web から実行するとクエリがタイムアウトしますが、SSMS から実行すると超高速です

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

質問

私が管理している Web アプリケーションで SQL タイムアウトの原因をデバッグしようとしています。C# コードのソース コードが手元にあるので、どのコードが実行されているかが正確にわかります。タイムアウトになる SQL コードを実行する行までアプリケーションをデバッグし、SQL プロファイラーでクエリの実行を監視しました。

このクエリを Web から実行すると、30 秒後にタイムアウトになります。ただし、プロファイラーに表示されているとおりにクエリをカット/ペーストし、それを SSMS に入力して実行すると、ほぼ即座に戻ります。Web が使用している接続で ARITHABORT が OFF に設定されていることが問題の原因であることがわかりました (つまり、SSMS セッションで ARITHABORT を OFF にすると長時間実行され、ON に戻すと実行されます)非常に迅速に)。しかし、ARITHABORTの説明を読むと、それは当てはまらないようです…。単純な SELECT を実行しているだけで、演算はまったく実行されていません。WHERE 条件を含む単一の INNER JOIN のみ:

この状況で ARITHABORT OFF がこの動作を引き起こすのはなぜですか??SSMS からその接続の ARITHABORT 設定を変更する方法はありますか?SQL Server 2008 を使用しています。

役に立ちましたか?

解決

では、C# コードはどのような方法を使用して SQL Server にアドホック SQL クエリを送信しているのでしょうか?ストアド プロシージャの使用を検討したことがありますか?そうすれば、誰が呼び出しても(少なくともエンジン内では)同じパフォーマンスが保証されるでしょう。

なぜ?ARITHABORT 設定は、オプティマイザがクエリの実行方法 (具体的にはプラン マッチング) を決定する際に確認するものの 1 つです。キャッシュ内のプランが SSMS と同じ設定である可能性があるため、キャッシュされたプランが使用されますが、逆の設定では、C# コードが強制的に再コンパイルされます (または、おそらく本当にエラーが発生します) 悪い キャッシュ内のプラン)、多くの場合、パフォーマンスに悪影響を与える可能性があります。

すでにストアド プロシージャを呼び出している場合 (クエリを投稿するつもりだったと思いますが、投稿しませんでした)、ストアド プロシージャ内の問題のあるクエリ (複数可) に OPTION (RECOMPILE) を追加してみてください。これは、これらのステートメントが常に再コンパイルされることを意味しますが、実行していると思われる不適切な計画の使用を防ぐことができます。もう 1 つのオプションは、ストアド プロシージャのコンパイル時に、SET ARITHABORT ON を使用してバッチが実行されるようにすることです。

最後に、SSMS で ARITHABORT 設定を変更する方法を尋ねているようです。あなたが質問したかったのは、コード内で ARITHABORT 設定を強制する方法だと思います。C# アプリからアドホック SQL を送信し続けることにした場合は、もちろん、セミコロンで区切られた複数のステートメントを含むテキストとしてコマンドを送信できます。例:

SET ARITHABORT ON; SELECT ...

この問題が発生する理由の詳細については、Erland Sommarskog の素晴らしい記事を参照してください。

他のヒント

この回答この問題を解決する方法が含まれます:

  

にかかわらず、ARITHABORT設定の期待通りにすべてのクエリを実行し、データベース上で管理者として次のコマンドを実行します。

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

更新

ほとんどの人は非常に稀にしか発生しないと、上記の技術はまともなワンタイム修正で、この問題を持ってしまうようです。何度もこの問題より具体的なクエリを呈する場合でも、この問題へのより長期的な解決策は、<のhref = "http://sqlperformance.com/2013/で説明したように、クエリは、OPTIMIZE FOROPTION(Recompile)のようなヒントを使用することです08 / T-SQL-クエリ/パラメータスニッフィング埋め込みアンド・再コンパイル・オプション」REL = "nofollowをnoreferrer">この記事。

私は何度も前にいますが、同じ問題がストアドプロシージャが問題を解決するドロップと再作成してストアドプロシージャを持っている場合は、この問題を持っていた。

これは、パラメータスニッフィングと呼ばれています。 あなたは、常に将来的にこの問題を回避するために、ストアドプロシージャ内のパラメータをローカライズする必要があります。

私は、これはオリジナルのポスターが何を望んではないかもしれませんが、同じ問題を持つ人を助けるかもしれない理解しています。

Entity Framework を使用する場合は、文字列値のクエリ パラメーターがデフォルトで nvarchar としてデータベースに送信されることに注意する必要があります。比較するデータベース列が varchar 型の場合、照合順序に応じて、クエリ実行プランで「IMPLICIT CONVERSION」ステップが必要になる場合があります。フルスキャンを強制します。実行計画を表示する、高価なクエリのデータベース監視オプションを調べることで確認できました。

最後に、この記事でこの動作について説明します。https://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-c​​ause-index-scans/

私は同じ問題を抱えていたし、それが「RECOMPILE WITH」の手順を実行することで修正されました。また、パラメータのスニッフィングを使用して試すことができます。私の問題は、SQLキャッシュに関連していました。

あなたは、未知のヒントのために最適化スニッフィングパラメータを修正するようにコードを変更することができた場合は、あなたの最良の選択肢です。あなたのコードを変更することができない場合は最良のオプションは、新しい実行計画を取得するだけで1つのストアドプロシージャを強制的に幹部SP_RECOMPILE「PROCの名前は」です。 PROCをドロップして再作成すると、同様の効果を持っているだろうが、誰かがそれを落としている間PROCを実行しようとするとエラーが発生することがあります。 DBCC FREEPROCCACHEは最大と重い取引の運用環境でタイムアウトの多くの原因となるなど、[OK]をクリックして、システムを大混乱を台無しことができ、すべてのキャッシュされたプランがドロップ。 ARITHABORTを設定すると、問題の解決策ではなく、パラメータのスニッフィングが問題になる場合を発見するための便利なツールです。

SMSSからSPを呼び出そうとWebアプリケーション(ASP.NET)から、それは約3分かかっている間、それは、2秒を取ったときます。

私は同じ問題を抱えています

私はすべての提案ソリューションのsp_recompileDBCC FREEPROCCACHEDBCC DROPCLEANBUFFERSを試してみたが、何も私の問題を修正していないが、それはトリックをした盗聴パラメータをしようとしたとき、およびうまく働きました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top