it-swarm.com.de

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

Daher habe ich festgestellt, dass das fehlerhafte Verhalten meines SQL Servers auf die Standardeinstellung von .Net SqlClient Data Provider von SET ARITHABORT OFF Zurückzuführen ist. 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 hinausgeht (und offensichtlich das Hinzufügen von SET in einem SP NICHT FUNKTIONIERT).

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

Welche Konsequenzen fehlen mir hier beim Einstellen dieser Instanz? Wie ich es sehe ... da SSMS diese Einstellung ON standardmäßig hat, sehe ich keinen Schaden darin, diese ON serverweit für alle Verbindungen festzulegen. Letztendlich brauche ich nur diesen SQL Server, um über alles zu arbeiten.

10
Eric Swiggum

Es gibt einige Standardeinstellungen, nur weil niemand wirklich weiß, wie sich eine Änderung auswirken würde. Die Standardkollatierung auf Instanzebene bei der Installation auf einem System, das "US-Englisch" als Betriebssystemsprache verwendet, lautet beispielsweise SQL_Latin1_General_CP1_CI_AS. Dies macht keinen Sinn, da die SQL_* - Kollatierungen der Kompatibilität vor SQL Server 2000 dienen. Ab SQL Server 2000 können Sie tatsächlich eine Windows-Sortierung auswählen. Daher wurde die Standardeinstellung für US-englische Systeme sollte in Latin1_General_CI_AS Geändert. 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. Setzen Sie es auf Instanzebene in Ihren Dev- und QA-Umgebungen auf ON und sehen Sie, wie das ein oder zwei Monate lang 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 ;-).

Also 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 .

(^ 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 aktiviert ARITHABORT, ohne andere möglicherweise festgelegte Optionen zu entfernen und ohne Änderungen vorzunehmen, wenn ARITHABORT bereits im bitmaskenhaften 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. ARITHABORT OFF Scheint keinen Vorteil zu haben.
  2. ARITHABORT ON Hat einen Vorteil
  3. Die Standardverbindungseinstellung (sofern nicht durch die Verbindung überschrieben) = OFF
  4. Es scheint nicht, dass entweder ODBC oder OLEDB/.NET SqlClient versuchen, ARITHABORT zu setzen, 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 nur die App aktualisieren if Sie finden ein Problem beim Ändern der instanzweiten Einstellung.

P.S. Ich habe einen einfachen Test mit dem Ändern von tempdb und nicht Ändern der instanzweiten Einstellung durchgeführt und es schien nicht zu funktionieren.

11
Solomon Rutzky