SET ARITHABORT ONがクエリを劇的に高速化するのはなぜですか?


75

クエリは、多くのグループ化レベルと集約操作を含む単一の選択です。SET ARITHABORT ONの場合は1秒未満で、それ以外の場合は数分かかります。この現象は、SQL Server 2000および2008で確認されています。

回答:


62

少し古いですが、ここで同じような問題を抱えている人には...

同じ問題がありました。私にとっては、パラメータスニッフィングであることが判明しましたが、最初は気にするほど理解していませんでした。私は問題を解決する「set arithabort on」を追加しましたが、その後に戻りました。次に読みました:

http://www.sommarskog.se/query-plan-mysteries.html

それはすべてをクリアしました。私はLinq to SQLを使用しており、問題を解決するためのオプションが限られていたため、クエリプランガイド(リンクの最後を参照)を使用して、必要なクエリプランを強制しました。


3
6年以上経っても、この回答に記載されているリンクはまだ「必読」であり、最新のものでもあり、最新の改訂版は17年12月です。
takrl

30

.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


この答えの半分に同意します。しかし、数値計算の主張については非常に懐疑的です!
マーティンスミス

2
@マーティン:私は不明瞭だったと思う。ARITHABORT ONにより、SQL Serverはdiv / 0または算術オーバーフローエラーでエラーになると言っていました。オフになっている間は継続し、何らかの理由であらゆる種類の恐ろしい問題を引き起こします。

@ベン-はい、申し訳ありませんが、あなたの答えを特に攻撃したくはありませんでした。SETオプションを変更すると、より良い計画を取得し、これが間違っているオプション自体であると誤解するのが非常に簡単だと指摘していました。私はあなたのリンクの人がこれをしていないと確信していません。
マーティンスミス

@Martin-問題ありません。あなたが私を攻撃しているとは思いませんでした。私がリンクした他の議論は、少し不明瞭かもしれません。裏付けとなる証拠を提供しようとしていました。

@Martin振り返ってみると、あなたは正しいと思います。

21

これはほぼ間違いなくパラメータースニッフィングであると主張します。

SET OPTIONSこのようにパフォーマンスに影響を与える可能性があるとよく言われますが、インデックス付きビュー/永続化された計算列を使用している場合を除き、この要求に対する単一の信頼できるソースはまだありません。

この場合(SQL2005 +およびデータベースがSQL2000互換モードでない場合)。あなたは両方を持っている場合ARITHABORTANSI_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セットが必要です。

プランキャッシュキーの完全なリストはこちら


13

私はこのパーティーに遅れていることを知っていますが、将来の訪問者にとって、マーティンは正確です。この同じ問題に遭遇しました。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自体は、クエリの最適化にマイナスの影響を与えることができることを示し、私たちのテストでは、マーティンが正しいことを確認-原因は、パラメータスニッフィングし、得られた計画は、パラメータのすべての範囲のために最適ではありません。


1
そのフレーズが何をSetting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.意味するのだろうか。計算列と計算ビューでインデックスを使用できないことについて話しているだけなのか(ANSI_WARNINGSオフの場合)、実際に他の効果があるのか​​どうか。
マーティンスミス

よく分かりません。MSDNの誰かが同様の状況に陥り、ARTIHABORTをONに設定し、パフォーマンスの改善を確認し、他の人が持っているのと同じ結論に飛びついたのは、単純な場合だろうか。インデックス付きビューと計算列に関しては、わかりません。ある時点で、INSERT、UPDATE、またはDELETE操作で格納されたデータ値を変更する場合、SETオプションには特定の値が必要であると記載されています。他の場所では、オプティマイザは、インデックス付きビューまたは計算列を参照する「クエリ」のインデックスを無視すると述べています。両方とも真実ですか、それとも本当に「データを変更するクエリ」ですか?
mdoyle

1

この問題が発生しました。ここで人々が言っ​​たように、根本的な原因は複数のクエリプランであり、そのうちの1つは最適ではありません。ARITHABORTがそれ自体で問題を引き起こす可能性があることを確認したかっただけです(私が問題を抱えていたクエリにはパラメーターがなく、パラメーターのスニッフィングが式から外されるため)。


1

これは、私が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パーミッションには、次の要件が存在することに注意してください。

この問題を確認するには、リンクされたサーバー側のインスタンスでプロファイラーを実行し、以下に示すように「エラーと警告」セクションでいくつかのイベントをオンにするだけです。

ここに画像の説明を入力してください

この経験が何らかの形でコミュニティに役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.