SQL Serverのすべての接続でARITHABORTをONに設定すると、どのような影響がありますか?


10

そのため、SQL Serverの不安定な動作は.Net SqlClientデータプロバイダーのデフォルト設定が原因であると判断しましたSET ARITHABORT OFF。そうは言っても、これを実装する最良の方法を議論するさまざまな記事を読んだことがあります。私にとっては、SQL Serverに問題があり、クエリのチューニングがアプリ全体で完全に超えていない(そして明らかにSETsp に追加しても機能しない)ため、簡単な方法が欲しいだけです。

Erland Sommarskogのこのトピックに関する素晴らしい記事では、基本的にアプリを変更SET ARITHABORT ONして接続用に発行することで安全なアプローチを取ることを提案しています。ただし、dba.stackexchange 質問からのこの回答では、Solomon Rutzkyがインスタンス全体とデータベース全体の両方のアプローチを提供しています。

これをインスタンス全体に設定すると、どのような影響がありますか?私が見ているように... SSMSにはONデフォルトでこれが設定されているONため、すべての接続に対してサーバー全体に設定しても問題はありません。結局のところ、何よりもこのSQL Serverを実行する必要があるだけです。


あなたが質問でリンクした私の回答の多くを読んで、今ではデフォルトでオフになっているようです、一部のクライアントは特にオンにしていますが、EF / SqlClientはそれに触れません、つまりオフのままです。
ソロモンルツキー

1
EFはありませんが、EFがインスタンス全体の設定をどのようにオーバーライドできるかについて興味深い点を挙げます。接続はこのメソッドをオーバーライドすることができますのであれば、明らかに最も信頼性の高い場所では、このセットは、SQL Serverに確立された接続内からである持っているすべての可能な場合...
エリックSwiggum

1
「ログオンセッションでは常にARITHABORTをONに設定してください。ARITHABORTをOFFに設定すると、クエリの最適化に悪影響を及ぼし、パフォーマンスの問題を引き起こす可能性があります。」マイクロソフトからこの記事は言う:docs.microsoft.com/en-us/sql/t-sql/statements/...
Shiwangini Shishulkar

私はさまざまなシナリオをテストしましたが、すべてからの私の最後の見方は、この設定とパラメーターのスニッフィングはおかしなものだということです。あなたが持っているならARITHABORT OFF、それで結構です。すべての着信接続に対してオフのままにします。(それを制御する幸運)。しかし、接続がONに設定された状態で接続が行われると、SQLは新しいクエリプランを生成し、これがパフォーマンスに影響を与える可能性があります。私の考えでは、それをインスタンスレベルでデフォルトのユーザーオプションとしてONに設定し、それに応じてクエリを調整します。
Eric Swiggum

回答:


11

デフォルトを変更することによる影響が誰にもわからないというだけの理由で、デフォルトがいくつか存在します。たとえば、OS言語として「米国英語」を使用するシステムにインストールする場合のデフォルトのインスタンスレベルの照合はSQL_Latin1_General_CP1_CI_ASです。SQL_*照合順序はSQL Server 2000以前の互換性のためのものなので、これは意味がありません。SQL Server 2000以降では、実際にはWindows照合順序を選択できるため、米国英語システムのデフォルトはに変更されているはずLatin1_General_CI_ASです。しかし、マイクロソフトの誰もが、さまざまな潜在的なサブシステムやシステムストアドプロシージャなどのすべてにどのような影響が及ぶかを本当に知っているとは思いません。

そのため、データベースのデフォルトまたはインスタンス全体としてONに設定したことによる特定の悪影響については知りません。同時に、私はそれをテストしていません。しかし、テストしたとしても、アプリケーションと同じコードパスを使用していない可能性があるため、これは実際に環境でテストする必要があるものです。に設定ON開発環境とQA環境のインスタンスレベルで、1〜2か月間どのように機能するかを確認します。次に、ステージング/ UATで有効にします。すべてが数週間うまくいく場合は、その構成変更を実稼働環境にロールします。重要なことは、毎日ヒットしないさまざまなコードパスをテストするために、できるだけ多くの時間を与えることです。一部は、毎週、数か月、または毎年ヒットします。一部のコードパスは、サポート、または誰かが何年も前に作成し、ユーザーに通知せずにランダムな間隔でのみ使用されるアドホックレポートまたはメンテナンス手順によってのみヒットします(いや、決して発生しません;-)。

それで、私はそれを変更したことがないので、デフォルトの「ユーザーオプション」設定がまだあるインスタンスでいくつかのテストを行いました。

ご注意ください:

  • @@OPTIONS/ 'user options'はビットマスクされた値です
  • 64は ARITHABORT ON

セットアップ

SQLCMD(ODBCを使用)とLINQPad(.NET SqlClientを使用)の両方でテストしました。

SQLCMD -W -S (local) ^
-Q"SELECT CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')') FROM sys.dm_exec_sessions ses WHERE ses.[session_id] = @@SPID;"
echo .

(これ^はDOS行継続文字です。.最後の行のは、余分な行を強制的にコピーして貼り付けやすくするためのものです)

LINQPadでは:

using (SqlConnection connection =
    new SqlConnection(@"Server=(local);Trusted_Connection=true;Database=tempdb;"))
{
  using (SqlCommand command = connection.CreateCommand())
  {
    command.CommandText = @"SELECT @RetVal =
CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')')
FROM  sys.dm_exec_sessions ses
WHERE ses.[session_id] = @@SPID;";
    SqlParameter paramRetVal = new SqlParameter("@RetVal", SqlDbType.NVarChar, 500);
    paramRetVal.Direction = ParameterDirection.Output;
    command.Parameters.Add(paramRetVal);

    connection.Open();
    command.ExecuteNonQuery();

    Console.WriteLine(paramRetVal.Value.ToString());
  }
}

テスト1:前

SQLCMDは次を返します:

master: 0 (ODBC)

LINQPadは次を返します:

tempdb: 0 (.Net SqlClient Data Provider)

デフォルトの接続オプションの変更:

次のT-SQLはARITHABORT、設定されている可能性のある他のオプションを削除せずに、またARITHABORT、ビットマスク値に既に設定されている場合は何も変更せずに有効にします。

DECLARE @UserOptions INT;

-- Get current bitmasked value and ensure ARITHABORT is enabled:
SELECT @UserOptions = CONVERT(INT, cnf.[value_in_use]) | 64 -- enable "ARITHABORT"
FROM   sys.configurations cnf
WHERE  cnf.[configuration_id] = 1534 -- user options

-- Apply new default connection options:
EXEC sys.sp_configure N'user options', @UserOptions;
RECONFIGURE;

テスト2:後

SQLCMDは次を返します:

master: 64 (ODBC)

LINQPadは次を返します:

tempdb: 64 (.Net SqlClient Data Provider)

結論

とすれば:

  1. 持っていることには何の利点もないようです ARITHABORT OFF
  2. 持つことには利点があります ARITHABORT ON
  3. デフォルトの接続設定(接続によってオーバーライドされない限り)= OFF
  4. ODBCまたはOLEDB / .NET SqlClientが設定を試みているようには見えないARITHABORTため、デフォルト設定を受け入れます

(上記のように)インスタンス全体のデフォルト接続オプションを変更することをお勧めします。これは、アプリケーションの更新よりも邪魔になりません。インスタンス全体の設定の変更で問題が見つかった場合にのみ、アプリを更新します。

PS私は、インスタンス全体の設定を変更して、変更tempdbずに簡単なテストを行いましたが、動作しないようです。


1
ええと、件名についてポールホワイトとのこのQ&Aを読んだ後、SET ANSI_WARNINGS ONを渡すと、暗黙的にARITHABORTがONに設定されるようです。ただし、接続でSET ARITHABORT OFFも渡された場合、ANSI_WARNINGSがそれを上書きしても、SQLサーバーは、奇妙な計画を選択する場合と同様に、ARITHABORTがOFFのように「動作」します。私はこれを見つけます...気が遠くなるほどで​​す。したがって、間違いなく、これは接続で設定する必要があり、SET ARITHABORT OFFは存在することさえできません。ケースは、私の目に閉鎖... sqlservercentral.com/forums/topic/...
エリックSwiggum

@EricSwiggumあなたが見つけた興味深いスレッド。ただし、その情報から、接続で設定する必要があるとどのように結論付けているのかわかりません。現在それをオーバーライドしているものSET ARITHABORT OFFない場合は存在しないことがわかります。それで、なぜそれが存在するのか心配するのですか?デフォルトがオーバーライドされる唯一の例は、SSMSがそれを設定することですON(これは良いことです)。いずれにせよ、私は自分の回答をテストで更新し、最も論理的な推奨事項(既存の情報ごと)として私が見ているものを更新しました。
ソロモンルツキー

1
私は同意し、インスタンス全体の設定をデフォルトとして有効にします。ただし、最終的には接続によって設定内容が制御されます。さまざまなテクノロジー/プロトコルがSQLに接続している共有インスタンスの場合はどうですか?つまり、私は走り回って、狂った男のように「SET ARITHABORT ON」を開発に叫ぶ必要がありますか?または、少なくとも、可能であればARITHABORT OFFの不在を促進します。また、これが、フルタイムのDBAとして6年目になるまで今まで見たことがないのも奇妙です。あるいは、私が十分に検討しなかった場合かもしれません。ポールまたはアーランドをバックアップしてください、LOL、これはどうですか?
Eric Swiggum、

@EricSwiggum 1)インスタンスレベルのデフォルトを変更する場合は、何も叫んで走り回る必要はありません。2)実際の発生率を見つけたARITHABORT OFF 場合にのみ欠勤を促進する必要があります。これまでのところ、おそらくありません。3)これはクエリプランに影響を与えるため、SQL Serverに特定の選択肢を検討させるのに十分なデータがテーブルに含まれていなかった可能性があります。あるいは、古くなった統計など、他の一時的な要因があるかもしれません。完全に定かではありません。
ソロモンルツキー

@EricSwiggum私はあなたに反対していません。これは、私の回答の冒頭で述べたもの(つまり、米国英語システムのデフォルトの照合)と非常に似ていると思います。アップグレード時にレガシーシステムでエラーが発生する(つまり、下位互換性の保証)のMicrosoftの恐れは、実際よりも害が大きい非理想的なシナリオのインストールベース/スコープを増やします。これにより、過去に留まることがますます増え、物事が良くなる可能性はますます低くなります。これらは、バンドエイドを剥ぎ取って、今すぐに痛みを取り除いた方が良い場合です。
ソロモンルツキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.