回答:
少し古いですが、ここで同じような問題を抱えている人には...
同じ問題がありました。私にとっては、パラメータスニッフィングであることが判明しましたが、最初は気にするほど理解していませんでした。私は問題を解決する「set arithabort on」を追加しましたが、その後に戻りました。次に読みました:
http://www.sommarskog.se/query-plan-mysteries.html
それはすべてをクリアしました。私はLinq to SQLを使用しており、問題を解決するためのオプションが限られていたため、クエリプランガイド(リンクの最後を参照)を使用して、必要なクエリプランを強制しました。
.NETアプリケーションは、デフォルトで無効になっているオプションで接続しますが、Management Studioではデフォルトで有効になっています。その結果、サーバーは実際にほとんど/すべての手順の2つの個別の実行計画をキャッシュします。これは、サーバーが数値計算を実行する方法に影響を与えるため、手順によって大幅に異なる結果を得ることができます。これは実際、procがひどい実行計画を受け取ることができる2つの一般的な方法のうちの1つにすぎず、もう1つはパラメータスニッフィングです。
見てくださいhttps://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performanceを。それについてのもう少しの議論のためのaspx。
SET
オプションを変更すると、より良い計画を取得し、これが間違っているオプション自体であると誤解するのが非常に簡単だと指摘していました。私はあなたのリンクの人がこれをしていないと確信していません。
これはほぼ間違いなくパラメータースニッフィングであると主張します。
SET OPTIONS
このようにパフォーマンスに影響を与える可能性があるとよく言われますが、インデックス付きビュー/永続化された計算列を使用している場合を除き、この要求に対する単一の信頼できるソースはまだありません。
この場合(SQL2005 +およびデータベースがSQL2000互換モードでない場合)。あなたは両方を持っている場合ARITHABORT
とANSI_WARNINGS
OFF
、あなたがそう求めたいのではなく、スキャンがあり、使用されていないインデックスを見つけるでしょう(と永続化計算結果として、いくつかのオーバーヘッドを使用することはできません)。ADO.NETのデフォルトANSI_WARNINGS ON
は、先ほど行った簡単なテストからです。
「サーバーが数値計算を実行する方法」は、そうでなければ1秒未満しかかからない結果に数分を追加できるというBenの答えの主張は、私には信用できないように思えます。起こりがちなのは、パフォーマンスパフォーマンスの問題を調査する際に、プロファイラーを使用して問題のあるクエリを識別することです。これは管理スタジオに貼り付けられ、すぐに実行されて結果が返されます。接続間の唯一の明らかな違いはARITH_ABORT
オプションです。
Management Studioウィンドウでの簡単なテストでSET ARITHABORT OFF
は、電源をオンにしてクエリを実行すると、パフォーマンスの問題が再発するため、明らかにケースが閉じられていることがわかります。実際、これはGregg Starkリンクで使用されているトラブルシューティング方法論のようです。
ただし、そのオプションセットを使用すると、キャッシュからまったく同じ不良プランを取得できるという事実は無視されます。
このプランの再利用は、アプリケーション接続が使用するユーザーとは異なるユーザーとしてログインしている場合でも発生する可能性があります。
最初にWebアプリケーションからテストクエリを実行し、次にManagement Studioからテストクエリを実行することでこれをテストSET ARITHABORT OFF
し、以下のクエリからusecountsが増加するのを確認できました。
SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
この共有pfプランを実際に発生させるには、すべてのプランキャッシュキーが同じでなければなりません。arithabort
それ自体と同様に、他のいくつかの例は、実行ユーザーが同じデフォルトスキーマを必要とし(クエリが暗黙的な名前解決に依存している場合)、接続に同じlanguage
セットが必要です。
私はこのパーティーに遅れていることを知っていますが、将来の訪問者にとって、マーティンは正確です。この同じ問題に遭遇しました。SPは.NETクライアントでは非常にゆっくり実行されていましたが、SSMSでは非常に高速でした。この問題の調査と解決において、ケニー・エビットがマーティンの質問へのコメントで尋ねる体系的なテストを行いました。
Martinのクエリのバリアントを使用して、プロシージャキャッシュでSPを探し、そのうちの2つを見つけました。計画を見ると、実際にはARITHABORTがオンであり、もう1つがARITHABORTがオフであるというケースでした。ARITHABORT OFFバージョンにはインデックスシークがありましたが、ARITHHABORT ONバージョンは同じ出力に対してインデックススキャンを使用していました。関連するパラメーターを考えると、インデックスシークでは、出力のために数千万のレコードを検索する必要があります。
キャッシュから2つの手順をクリアし、同じパラメーターを使用して.NETクライアントにSPを再度実行させました(これは、多くのアクティビティがある顧客のために幅広い日付範囲を特徴としていました)。SPはすぐに戻りました。キャッシュされたプランは、以前はARITHABORT ONプランで紹介されていたものと同じインデックススキャンを使用しましたが、今回はARITHABORT OFFのプランでした。SSMSで同じパラメータを使用してSPを実行すると、すぐに結果が得られました。これで、ARITHABORT ONの2番目のプランがインデックススキャンでキャッシュされたことがわかりました。
その後、キャッシュをクリアし、狭い日付範囲でSPをSSMSで実行し、すぐに結果を得ました。同じ出力が以前にスキャンで処理されていたため、結果のキャッシュされたプランにはインデックスシークがあることがわかりました(これはARITHABORT OFFの元のプランでもシークでした)。再びSSMSから、今回は同じ広い日付範囲でSPを実行しましたが、元の.NETリクエストと同じひどいパフォーマンスが見られました。
つまり、この不一致はARITHABORTの実際の値とは関係ありませんでした。どちらのクライアントからでも、オンまたはオフにすると、許容可能なパフォーマンスまたはひどいパフォーマンスを得ることができました。
一方でMSDNが ARITHABORT OFF自体は、クエリの最適化にマイナスの影響を与えることができることを示し、私たちのテストでは、マーティンが正しいことを確認-原因は、パラメータスニッフィングし、得られた計画は、パラメータのすべての範囲のために最適ではありません。
Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.
意味するのだろうか。計算列と計算ビューでインデックスを使用できないことについて話しているだけなのか(ANSI_WARNINGS
オフの場合)、実際に他の効果があるのかどうか。
この問題が発生しました。ここで人々が言ったように、根本的な原因は複数のクエリプランであり、そのうちの1つは最適ではありません。ARITHABORTがそれ自体で問題を引き起こす可能性があることを確認したかっただけです(私が問題を抱えていたクエリにはパラメーターがなく、パラメーターのスニッフィングが式から外されるため)。
これは、私がSQL Server 2008で経験したのとまったく同じ問題を思い出させます。私たちのケースでは、1つのSQLジョブが突然遅くなり(通常は数秒で、今では9分以上)、ジョブがリンクサーバーにアクセスする必要があることがわかりました。数日間解決されてから返されました。
後にMSサポートのチケットを開きましたが、最初はどちらも見つけられず、チケットは非常に上級のPFEチームにエスカレートされ、2人のサポートPFEがこの問題を見つけようとしました。
最後の理由は、(ジョブステップを実行するための)ユーザー資格情報が(リンクサーバー側の)基になるテーブルの統計にアクセスできないため、実行計画が最適化されないことです。
詳細には、ユーザーにはDBCC SHOW_STATISTICSに対する権限がありません(ただし、ユーザーはテーブルから選択できます)。MSDNによると、この許可ルールはSQL 2012 SP1の後に変更されます
SQL ServerおよびSQLデータベースの権限
統計オブジェクトを表示するには、ユーザーがテーブルを所有しているか、固定サーバーロールsysadmin、固定データベースロールdb_owner、または固定データベースロールdb_ddladminのメンバーである必要があります。
SQL Server 2012 SP1は権限の制限を変更し、 SELECT権限を持つユーザーがこのコマンドを使用できるようにします。コマンドを実行するのに十分なSELECTパーミッションには、次の要件が存在することに注意してください。
この問題を確認するには、リンクされたサーバー側のインスタンスでプロファイラーを実行し、以下に示すように「エラーと警告」セクションでいくつかのイベントをオンにするだけです。
この経験が何らかの形でコミュニティに役立つことを願っています。