Welche Auswirkungen hat das Festlegen von ARITHABORT ON für alle Verbindungen in SQL Server?

10

Daher habe ich festgestellt, dass das fehlerhafte Verhalten meines SQL Servers auf die Standardeinstellung von .Net SqlClient Data Provider von zurückzuführen ist SET ARITHABORT OFF. Vor diesem Hintergrund habe ich verschiedene Artikel gelesen, in denen der beste Weg zur Umsetzung diskutiert wird. Für mich möchte ich nur einen einfachen Weg, weil SQL Server leidet und meine Abfrageoptimierung nicht vollständig über die App SEThinausgeht (und das Hinzufügen in einem SP funktioniert natürlich NICHT).

In Erland Sommarskogs brillantem Artikel über das Thema schlägt er grundsätzlich vor, den sicheren Ansatz zu wählen , indem die zu ändernde App SET ARITHABORT ONfür die Verbindung geändert wird . In dieser Antwort auf eine Frage zu dba.stackexchange bietet Solomon Rutzky jedoch sowohl einen instanzweiten als auch einen datenbankweiten Ansatz.

Welche Konsequenzen fehlen mir hier beim Einstellen dieser Instanz? Aus meiner Sicht ... da SSMS dies ONstandardmäßig festgelegt hat, kann es nicht schaden, diese Serverweite ONfür alle Verbindungen festzulegen . Letztendlich brauche ich nur diesen SQL Server, um über alles zu arbeiten.

Eric Swiggum
quelle
Wenn Sie einen Großteil meiner Antwort lesen, auf die Sie in der Frage verwiesen haben, scheint es nun standardmäßig AUS zu sein. Einige Clients schalten sie speziell ein, aber EF / SqlClient berühren sie nicht, was bedeutet, dass sie AUS bleibt.
Solomon Rutzky
1
Keine EF, aber Sie sprechen einen interessanten Punkt an, wie EF die instanzweite Einstellung überschreiben kann. Wenn eine Verbindung dies überschreiben kann, ist der zuverlässigste Ort, an dem dieser Satz eingerichtet werden kann, offensichtlich die Verbindung zu SQL Server, wenn dies überhaupt möglich ist ...
Eric Swiggum
1
"Setzen Sie ARITHABORT in Ihren Anmeldesitzungen immer auf EIN. Wenn Sie ARITHABORT auf AUS setzen, kann sich dies negativ auf die Abfrageoptimierung auswirken und zu Leistungsproblemen führen." Dieser Artikel von Microsoft sagt: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar
Ich habe verschiedene Szenarien getestet. Meine letzte Annahme ist, dass diese Einstellung und das Parameter-Sniffing Bettgenossen sind. Wenn ja ARITHABORT OFF, dann gut. Halten Sie es für alle eingehenden Verbindungen ausgeschaltet. (Viel Glück beim Kontrollieren). Wenn jedoch eine Verbindung mit der Einstellung ON eingeht, generiert SQL einen neuen Abfrageplan. Dies kann sich auf die Leistung auswirken. Mein Take, setzen Sie es als Standardbenutzeroption auf Instanzebene auf ON und optimieren Sie Abfragen entsprechend.
Eric Swiggum

Antworten:

11

Es gibt einige Standardeinstellungen, nur weil niemand wirklich weiß, wie sich eine Änderung auswirken würde. Beispiel: Die Standardkollation auf Instanzebene bei der Installation auf einem System, das "US-Englisch" als Betriebssystemsprache verwendet SQL_Latin1_General_CP1_CI_AS. Dies ist nicht sinnvoll, da die SQL_*Sortierungen aus Gründen der Kompatibilität vor SQL Server 2000 dienen. Ab SQL Server 2000 Sie könnten eine Windows - Sortierung tatsächlich wählen und so den Standard für US - Englisch Systeme sollten geändert wurden Latin1_General_CI_AS. ABER ich denke, niemand bei Microsoft weiß wirklich, welche Auswirkungen dies auf die verschiedenen potenziellen Subsysteme und gespeicherten Systemprozeduren usw. haben wird.

Daher sind mir keine spezifischen negativen Auswirkungen der Einstellung auf ON als Datenbankstandard oder sogar instanzweit bekannt. Gleichzeitig habe ich es nicht getestet. Aber selbst wenn ich es getestet hätte, würde ich möglicherweise nicht dieselben Codepfade wie Ihre Anwendung verwenden. Dies ist also etwas, das Sie wirklich in Ihrer Umgebung testen müssen. Stellen Sie es aufONauf Instanzebene in Ihren Entwicklungs- und QS-Umgebungen und sehen Sie, wie das für ein oder zwei Monate funktioniert. Aktivieren Sie es dann in Staging / UAT. Wenn mehrere Wochen lang alles gut läuft, ändern Sie diese Konfigurationsänderung in Produktion. Der Schlüssel besteht darin, so viel Zeit wie möglich für das Testen verschiedener Codepfade zu geben, die nicht täglich aufgerufen werden. Einige werden wöchentlich oder monatelang oder jährlich getroffen. Einige Codepfade werden nur vom Support oder von einem Ad-hoc-Bericht oder Wartungsprozess getroffen, den jemand vor Jahren erstellt hat und der Ihnen nie davon erzählt hat und der nur in zufälligen Abständen verwendet wird (nein, das passiert nie ;-).

Daher habe ich einige Tests an einer Instanz durchgeführt, die immer noch die Standardeinstellung "Benutzeroptionen" hat, da ich sie nie geändert habe.

Bitte beachten Sie:

  • @@OPTIONS/ 'user options'ist ein bitmaskender Wert
  • 64 ist das Bit für ARITHABORT ON

INSTALLIEREN

Ich habe sowohl mit SQLCMD (das ODBC verwendet) als auch mit LINQPad (das .NET SqlClient verwendet) getestet:

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 .

(Dies ^ist das DOS-Zeilenfortsetzungszeichen. Das .in der letzten Zeile dient nur dazu, die zusätzliche Zeile zu erzwingen, um das Kopieren und Einfügen zu vereinfachen.)

In 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());
  }
}

TEST 1: Vorher

SQLCMD gibt zurück:

master: 0 (ODBC)

LINQPad gibt Folgendes zurück:

tempdb: 0 (.Net SqlClient Data Provider)

STANDARDVERBINDUNGSOPTION ÄNDERN:

Das folgende T-SQL wird aktiviert, ARITHABORTohne dass andere Optionen entfernt werden, die möglicherweise festgelegt wurden, und ohne dass etwas ARITHABORTgeändert wird , wenn dies bereits im bitmaskenen Wert festgelegt ist.

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;

TEST 2: Nachher

SQLCMD gibt zurück:

master: 64 (ODBC)

LINQPad gibt Folgendes zurück:

tempdb: 64 (.Net SqlClient Data Provider)

Fazit

Vorausgesetzt, dass:

  1. Es scheint keinen Vorteil zu haben ARITHABORT OFF
  2. Es hat Vorteile zu haben ARITHABORT ON
  3. Die Standardverbindungseinstellung (sofern nicht durch die Verbindung überschrieben) = OFF
  4. Es scheint nicht, dass ODBC oder OLEDB / .NET SqlClient versuchen, eine Einstellung vorzunehmen ARITHABORT, daher akzeptieren sie die Standardeinstellung

Ich würde vorschlagen, die instanzweiten Standardverbindungsoptionen zu ändern (wie oben gezeigt). Dies wäre weniger aufdringlich als das Aktualisieren der Anwendung. Ich würde die App nur aktualisieren, wenn Sie ein Problem beim Ändern der instanzweiten Einstellung finden.

PS Ich habe einen einfachen Test durchgeführt, bei dem die instanzweite Einstellung geändert tempdbund nicht geändert wurde, und es schien nicht zu funktionieren.

Solomon Rutzky
quelle
1
Nach dem Lesen dieser Fragen und Antworten mit Paul White zu diesem Thema scheint es, dass durch das Übergeben von SET ANSI_WARNINGS ON ARITHABORT implizit auf ON gesetzt wird. Wenn jedoch SET ARITHABORT OFF auch in der Verbindung übergeben wird, selbst wenn ANSI_WARNINGS diese überschreibt, "verhält" sich der SQL Server immer noch so, als wäre ARITHABORT OFF, wie bei der Auswahl seltsamer Pläne. Ich finde das ... umwerfend. Ohne Zweifel muss dies in der Verbindung eingestellt werden und SET ARITHABORT OFF kann nicht einmal existieren. Fall in meinen Augen geschlossen ... sqlservercentral.com/forums/topic/…
Eric Swiggum
@EricSwiggum Interessanter Thread, den Sie gefunden haben. Ich sehe jedoch nicht, wie Sie aus diesen Informationen schließen, dass sie in der Verbindung festgelegt werden müssen. Wenn nichts zur Zeit es überschrieben wird, dann wissen wir , dass SET ARITHABORT OFFist nicht vorhanden. Warum also Sorgen machen, dass es vorhanden ist? Die einzige Instanz, bei der wir gesehen haben, dass der Standardwert überschrieben wird, ist die SSMS-Einstellung ON(was gut ist). In beiden Fällen habe ich meine Antwort mit Tests und der meiner Meinung nach logischsten Empfehlung (gemäß den vorhandenen Informationen) aktualisiert.
Solomon Rutzky
1
Ich bin damit einverstanden, aktivieren Sie die instanzweite Einstellung als Standard. Aber letztendlich steuert die Verbindung, was eingestellt ist. Was ist mit gemeinsam genutzten Instanzen, in denen verschiedene Technologien / Protokolle eine Verbindung zu SQL herstellen? Ich meine, muss ich herumlaufen und "SET ARITHABORT ON" schreien, um mich wie ein Verrückter zu entwickeln? oder zumindest, wenn möglich, das Fehlen von ARITHABORT OFF fördern. Ich finde es auch seltsam, dass sich dies bis jetzt, meinem sechsten Jahr als Vollzeit-DBA, nicht zuspitzt. oder vielleicht ist es ein Fall, in dem ich mich nicht genau genug damit befasst habe. Unterstütze mich, Paul oder Erland, LOL, was ist damit los?
Eric Swiggum
@EricSwiggum 1) Sie müssten nichts herumschreien, wenn Sie die Standardeinstellung auf Instanzebene ändern. 2) Sie müssten das Fehlen von nur fördern, ARITHABORT OFF wenn Sie tatsächliche Vorkommnisse finden. Bisher gibt es wahrscheinlich keine. 3) Da dies Abfragepläne betrifft, könnte es sein, dass die Tabellen nie über genügend Daten verfügten, um SQL Server zu veranlassen, bestimmte Auswahlmöglichkeiten zu berücksichtigen, wobei jetzt mehr Auswahlmöglichkeiten vorhanden sind und einige schlecht sind. Oder vielleicht gibt es andere vorübergehende Faktoren, wie veraltete Statistiken usw. Nicht ganz sicher.
Solomon Rutzky
@ EricSwiggum Ich bin da nicht anderer Meinung als du. Ich denke, dies ist sehr ähnlich zu dem, was ich zu Beginn meiner Antwort erwähnt habe (dh die Standardkollation für US-englische Systeme): Die Angst von Microsoft, dass Legacy-Systeme beim Upgrade Fehler erhalten (dh Abwärtskompatibilitätsgarantie), schadet mehr als es nützt erhöht die Installationsbasis / den Umfang des nicht idealen Szenarios. Dies macht es zu einer immer größeren Anziehungskraft, in der Vergangenheit zu bleiben, und zu einer immer geringeren Wahrscheinlichkeit, dass die Dinge besser werden. Dies sind Fälle, in denen es besser ist, das Pflaster abzureißen und den Schmerz jetzt zu überwinden.
Solomon Rutzky