Quali sono le conseguenze dell'impostazione di ARITHABORT su tutte le connessioni in SQL Server?


10

Quindi ho determinato che il comportamento irregolare del mio SQL Server è dovuto all'impostazione predefinita di .Net SqlClient Data Provider SET ARITHABORT OFF. Detto questo, ho letto vari articoli che discutono il modo migliore per implementarlo. Per me, voglio solo un modo semplice perché SQL Server sta soffrendo e la mia ottimizzazione delle query non è stata completamente trascesa attraverso l'app (e ovviamente aggiungendo il comando SETin un sp NON FUNZIONA).

Nel brillante articolo di Erland Sommarskog sull'argomento, in sostanza suggerisce di adottare un approccio sicuro alterando l'app da emettere SET ARITHABORT ONper la connessione. Tuttavia, in questa risposta da una domanda dba.stackexchange , Solomon Rutzky offre un approccio sia a livello di istanza che a livello di database.

Quali ramificazioni mi sto perdendo qui con l'impostazione di questa istanza a livello? Per come la vedo io ... dato che SSMS ha questo set ONdi default, non vedo alcun danno nell'impostare questo ONserver per tutte le connessioni. Alla fine, ho solo bisogno che questo SQL Server funzioni al di sopra di tutto.


Leggendo gran parte della mia risposta a cui sei collegato nella domanda, ora sembra che sia OFF di default, alcuni client lo attivano specificamente, ma EF / SqlClient non lo tocca, il che significa che rimane come OFF.
Solomon Rutzky,

1
Nessun EF, ma sollevi un punto interessante su come EF può ignorare l'impostazione a livello di istanza. Quindi, se una connessione può sovrascrivere questo, ovviamente il posto più affidabile per avere questo set è all'interno della connessione stabilita a SQL Server, se possibile ...
Eric Swiggum,

1
"Impostare sempre ARITHABORT su ON nelle sessioni di accesso. L'impostazione di ARITHABORT su OFF può influire negativamente sull'ottimizzazione delle query, causando problemi di prestazioni." questo articolo di Microsoft dice: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar

Ho testato vari scenari, il mio punto di vista finale è che questa impostazione e lo sniffing dei parametri sono compagni di letto. Se hai ARITHABORT OFF, allora bene. Tenerlo spento per tutte le connessioni in entrata. (Buona fortuna a controllarlo). Ma quando arriva una connessione impostata su ON, SQL genera un nuovo piano di query e questo potrebbe influire sulle prestazioni. Mio take, impostarlo su ON come opzione utente predefinita a livello di istanza e ottimizzare le query di conseguenza.
Eric Swiggum,

Risposte:


11

Ci sono alcune impostazioni predefinite che esistono semplicemente perché nessuno sa davvero quale sarebbe l'effetto di cambiarle. Ad esempio, il confronto a livello di istanza predefinito durante l'installazione su un sistema che utilizza "inglese americano" come lingua del sistema operativo è SQL_Latin1_General_CP1_CI_AS. Ciò non ha senso poiché le SQL_*regole di confronto sono compatibili con SQL Server 2000. A partire da SQL Server 2000 si potrebbe effettivamente scegliere un confronto di Windows, quindi l'impostazione predefinita per i sistemi inglesi statunitensi avrebbe dovuto essere modificata Latin1_General_CI_AS. MA, suppongo che nessuno in Microsoft sappia davvero quale sarà l'impatto su tutti i vari sottosistemi potenziali e sulle procedure memorizzate di sistema, ecc.

Quindi, non sono a conoscenza di alcun impatto negativo specifico dell'impostazione su ON come predefinito del database o anche a livello di istanza. Allo stesso tempo, non l'ho provato. Ma anche se lo avessi testato, potrei ancora non utilizzare gli stessi percorsi di codice della tua applicazione, quindi questo è qualcosa che devi davvero testare nel tuo ambiente. Impostalo suONa livello di istanza nei tuoi ambienti Dev e QA e scopri come funziona per un mese o due. Quindi abilitalo in Staging / UAT. Se tutto continua a funzionare bene per diverse settimane, ruota la configurazione in Modifica. La chiave è dedicare più tempo possibile al test di vari percorsi di codice che non vengono raggiunti quotidianamente. Alcuni vengono colpiti settimanalmente o mesi o annualmente. Alcuni percorsi di codice sono colpiti solo dal supporto o da un rapporto ad hoc o da un proc di manutenzione che qualcuno ha creato anni fa e di cui non ti ha mai parlato e che viene utilizzato solo a intervalli casuali (nah, ciò non accade mai ;-).

Quindi, ho fatto alcuni test su un'istanza che ha ancora l'impostazione predefinita "opzioni utente" in quanto non l'ho mai cambiata.

Notare che:

  • @@OPTIONS/ 'user options'è un valore con maschera di bit
  • 64 è il bit per ARITHABORT ON

IMPOSTARE

Ho testato sia con SQLCMD (che utilizza ODBC) sia LINQPad (che utilizza .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 .

( ^è il carattere di continuazione della riga DOS; l' .ultima riga serve solo a forzare la riga aggiuntiva per facilitare il copia e incolla)

Nel 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: Prima

Restituisce SQLCMD:

master: 0 (ODBC)

Restituisce LINQPad:

tempdb: 0 (.Net SqlClient Data Provider)

MODIFICA OPZIONE DI CONNESSIONE PREDEFINITA:

Il seguente T-SQL abilita ARITHABORTsenza rimuovere altre opzioni che potrebbero essere impostate e senza modificare nulla se ARITHABORTè già impostato nel valore con maschera di bit.

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: Dopo

Restituisce SQLCMD:

master: 64 (ODBC)

Restituisce LINQPad:

tempdb: 64 (.Net SqlClient Data Provider)

Conclusione

Dato che:

  1. Non sembra esserci alcun vantaggio nell'avere ARITHABORT OFF
  2. C'è un vantaggio nell'avere ARITHABORT ON
  3. L'impostazione di connessione predefinita (a meno che non venga ignorata dalla connessione) = OFF
  4. Non sembra che ODBC o OLEDB / .NET SqlClient tentino di impostare ARITHABORT, quindi accettano l'impostazione predefinita

Suggerirei di modificare le opzioni di connessione predefinite a livello di istanza (come mostrato sopra). Questo sarebbe meno invadente rispetto all'aggiornamento dell'applicazione. Vorrei aggiornare l'app solo se riscontri un problema con la modifica delle impostazioni a livello di istanza.

PS Ho fatto un semplice test cambiando tempdbe non cambiando l'impostazione a livello di istanza e non sembrava funzionare.


1
Huh, dopo aver letto queste domande e risposte con Paul White sull'argomento, sembra che passando SET ANSI_WARNINGS ON, imposti implicitamente ARITHABORT su ON. Tuttavia, se SET ARITHABORT OFF viene passato anche nella connessione, anche con ANSI_WARNINGS che lo ignora, il server SQL continuerà a "agire" come ARITHABORT è OFF, come nella scelta di piani strani. Lo trovo ... da capogiro. Quindi, senza dubbio, questo deve essere impostato nella connessione e SET ARITHABORT OFF non può nemmeno esistere. Caso chiuso nei miei occhi ... sqlservercentral.com/forums/topic/…
Eric Swiggum

@EricSwiggum Discussione interessante che hai trovato. Tuttavia, non vedo come si possa concludere da quelle informazioni che deve essere impostato nella connessione. Se nulla lo sta attualmente ignorando, allora sappiamo che nonSET ARITHABORT OFF è presente. Quindi perché preoccuparsi della sua presenza? l'unica istanza che abbiamo visto in cui viene sovrascritto il valore predefinito è l'impostazione di SSMS (che è una buona cosa). Ad ogni modo, ho aggiornato la mia risposta con i test e quella che vedo come la raccomandazione più logica (per informazioni esistenti). ON
Solomon Rutzky,

1
Sono d'accordo, abilitare l'impostazione a livello di istanza come predefinita. Ma alla fine la connessione controlla ciò che è impostato. Che dire del caso delle istanze condivise in cui varie tecnologie / protocolli si connettono a SQL? Voglio dire, devo correre e urlare "SET ARITHABORT ON" allo sviluppo come un matto? o per lo meno, promuovi l'assenza di ARITHABORT OFF, se possibile .. Trovo anche strano che non abbia mai visto questo arrivare fino ad ora, il mio sesto anno da DBA a tempo pieno. o forse è un caso in cui non l'ho esaminato abbastanza duramente. Back up Paul o Erland, LOL, che succede?
Eric Swiggum,

@EricSwiggum 1) Non dovrai correre in giro urlando nulla se cambi l'impostazione predefinita a livello di istanza. 2) Avresti solo bisogno di promuovere l'assenza di ARITHABORT OFF se ne riscontri reali incidenti. Finora probabilmente non ce ne sono. 3) Poiché ciò influisce sui piani di query, è possibile che le tabelle non abbiano mai avuto abbastanza dati da indurre SQL Server a prendere in considerazione alcune scelte, dove ora ci sono più scelte e alcune sono sbagliate. O forse ci sono altri fattori transitori, come statistiche obsolete, ecc. Non del tutto sicuro.
Solomon Rutzky

@EricSwiggum Non sono in disaccordo con te lì. Penso che questo sia molto simile a quello che ho menzionato all'inizio della mia risposta (ovvero le regole di confronto predefinite per i sistemi inglesi statunitensi): la paura di Microsoft di sistemi legacy che ottengono errori durante l'aggiornamento (ovvero la garanzia di compatibilità con le versioni precedenti) fa più male che bene come in realtà aumenta la base di installazione / ambito dello scenario non ideale. Questo rende sempre più difficile rimanere nel passato e una possibilità in costante diminuzione di migliorare le cose. Questi sono casi in cui è meglio strappare il cerotto e rimediare al dolore ora.
Solomon Rutzky
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.