¿Cuáles son las ramificaciones de configurar ARITHABORT ON para todas las conexiones en SQL Server?

10

Así que he determinado que el comportamiento errático de mi SQL Server se debe a la configuración predeterminada de .Net SqlClient Data Provider de SET ARITHABORT OFF. Dicho esto, he leído varios artículos que debaten la mejor manera de implementar esto. Para mí, solo quiero una manera fácil porque SQL Server está sufriendo y mi ajuste de consultas no ha trascendido completamente a través de la aplicación (y obviamente agregar el SETen un sp NO FUNCIONA).

En el brillante artículo de Erland Sommarskog sobre el tema, básicamente sugiere adoptar un enfoque seguro alterando la aplicación para emitir SET ARITHABORT ONla conexión. Sin embargo, en esta respuesta de una pregunta dba.stackexchange , Solomon Rutzky ofrece un enfoque tanto para la instancia como para la base de datos.

¿Qué ramificaciones me estoy perdiendo aquí al configurar esta instancia en toda la instancia? Tal como lo veo ... ya que SSMS tiene este conjunto ONpor defecto, no veo ningún daño en configurar este ONservidor para todas las conexiones. Al final del día, solo necesito que este SQL Server funcione por encima de todo lo demás.

Eric Swiggum
fuente
Al leer gran parte de mi respuesta a la que se vinculó en la pregunta, ahora parece que está DESACTIVADA de manera predeterminada, algunos clientes la activan específicamente, pero EF / SqlClient no la toca, lo que significa que permanece DESACTIVADA.
Solomon Rutzky
1
Sin EF, pero plantea un punto interesante sobre cómo EF puede anular la configuración de toda la instancia. Entonces, si una conexión puede anular esto, obviamente, el lugar más confiable para tener este conjunto es desde dentro de la conexión establecida a SQL Server, si es posible ...
Eric Swiggum
1
"Siempre configure ARITHABORT en ON en sus sesiones de inicio de sesión. Establecer ARITHABORT en OFF puede afectar negativamente la optimización de la consulta, lo que lleva a problemas de rendimiento". Este artículo de Microsoft dice: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar
He probado varios escenarios, mi opinión final de todos es que esta configuración y la detección de parámetros son compañeros de cama. Si es así ARITHABORT OFF, entonces está bien. Manténgalo apagado para todas las conexiones entrantes. (Buena suerte controlando eso). Pero cuando entra una conexión configurada en ON, SQL genera un nuevo plan de consulta y esto podría afectar el rendimiento. Mi opinión, configúrelo como la opción de usuario predeterminada en el nivel de instancia y ajuste las consultas en consecuencia.
Eric Swiggum

Respuestas:

11

Existen algunos valores predeterminados simplemente porque nadie sabe realmente cuál sería el efecto de cambiarlos. Por ejemplo, la clasificación predeterminada de nivel de instancia cuando se instala en un sistema que usa "inglés de EE. UU." Como el idioma del sistema operativo SQL_Latin1_General_CP1_CI_AS. Esto no tiene sentido ya que las SQL_*intercalaciones son para compatibilidad anterior a SQL Server 2000. A partir de SQL Server 2000, en realidad podría elegir una intercalación de Windows, por lo que el valor predeterminado para los sistemas de inglés de EE. UU. Debería haberse cambiado a Latin1_General_CI_AS. PERO, supongo que nadie en Microsoft realmente sabe cuál será el impacto en todos los diversos subsistemas potenciales y procedimientos almacenados del sistema, etc.

Por lo tanto, no tengo conocimiento de ningún impacto negativo específico de establecerlo en ON como valor predeterminado de la base de datos o incluso en toda la instancia. Al mismo tiempo, no lo he probado. Pero incluso si lo hubiera probado, aún podría no usar las mismas rutas de código que su aplicación, por lo que esto es algo que realmente necesita probar en su entorno. Establecerlo enONa nivel de instancia en sus entornos de desarrollo y control de calidad y vea cómo funciona durante un mes o dos. Luego habilítelo en Staging / UAT. Si todo continúa bien durante varias semanas, pasa el cambio de configuración a Producción. La clave es dar el mayor tiempo posible para probar varias rutas de código que no se aplican diariamente. Algunos son golpeados semanalmente o meses o anualmente. Algunas rutas de código solo se ven afectadas por el soporte, o algún informe ad hoc o proceso de mantenimiento que alguien creó hace años y que nunca le contó y solo se usa a intervalos aleatorios (nah, eso nunca sucede ;-).

Entonces, hice algunas pruebas en una instancia que todavía tiene la configuración predeterminada de "opciones de usuario" ya que nunca la he cambiado.

Tenga en cuenta:

  • @@OPTIONS/ 'user options'es un valor enmascarado
  • 64 es el bit para ARITHABORT ON

PREPARAR

Probé con SQLCMD (que usa ODBC) y LINQPad (que usa .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 .

(este ^es el carácter de continuación de línea de DOS; el .de la última línea es solo para forzar la línea adicional para que sea más fácil copiar y pegar)

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

PRUEBA 1: Antes

SQLCMD devuelve:

master: 0 (ODBC)

LINQPad devuelve:

tempdb: 0 (.Net SqlClient Data Provider)

CAMBIAR LA OPCIÓN DE CONEXIÓN POR DEFECTO:

El siguiente T-SQL se habilita ARITHABORTsin eliminar ninguna otra opción que pueda establecerse, y sin cambiar nada si ARITHABORTya está configurado en el valor de máscara de bits.

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;

PRUEBA 2: Después

SQLCMD devuelve:

master: 64 (ODBC)

LINQPad devuelve:

tempdb: 64 (.Net SqlClient Data Provider)

Conclusión

Dado que:

  1. No parece haber ningún beneficio al tener ARITHABORT OFF
  2. Es beneficioso tener ARITHABORT ON
  3. La configuración de conexión predeterminada (a menos que la conexión la anule) = OFF
  4. No parece que ODBC o OLEDB / .NET SqlClient intenten establecer ARITHABORT, por lo tanto, aceptan la configuración predeterminada

Sugeriría cambiar las opciones de conexión predeterminadas de toda la instancia (como se muestra arriba). Esto sería menos molesto que actualizar la aplicación. Solo actualizaría la aplicación si encuentra un problema al cambiar la configuración de toda la instancia.

PD: hice una prueba simple con cambiar tempdby no cambiar la configuración de toda la instancia y no parecía funcionar.

Solomon Rutzky
fuente
1
Huh, después de leer estas preguntas y respuestas con Paul White sobre el tema, parece que pasar SET ANSI_WARNINGS ON, implícitamente establece ARITHABORT en ON. SIN EMBARGO, si SET ARITHABORT OFF también se pasa en la conexión, incluso con ANSI_WARNINGS reemplazándolo, el servidor SQL seguirá "actuando" como ARITHABORT está OFF, como al elegir planes extraños. Esto me parece ... alucinante. Entonces, sin duda, esto debe establecerse en la conexión Y SET ARITHABORT OFF ni siquiera puede existir. Caso cerrado en mis ojos ... sqlservercentral.com/forums/topic/…
Eric Swiggum
@EricSwiggum Hilo interesante que encontraste. Sin embargo, no veo cómo deduces de esa información que debe establecerse en la conexión. Si nada lo anula actualmente, entonces sabemos que noSET ARITHABORT OFF está presente. Entonces, ¿por qué preocuparse de que esté presente? la única instancia que hemos visto donde se anula el valor predeterminado es SSMS configurándolo en (que es algo bueno). De cualquier manera, he actualizado mi respuesta con pruebas y lo que veo como la recomendación más lógica (según la información existente).ON
Solomon Rutzky
1
Estoy de acuerdo, habilite la configuración de toda la instancia como predeterminada. Pero, en última instancia, la conexión controla lo que se establece. ¿Qué pasa con el caso de instancias compartidas donde varias tecnologías / protocolos se conectan a SQL? Quiero decir, ¿tengo que correr y gritar "SET ARITHABORT ON" al desarrollo como un loco? o al menos, promueva la ausencia de ARITHABORT OFF si es posible ... También me parece extraño que no haya visto esto hasta ahora, mi sexto año como DBA a tiempo completo. o tal vez es un caso en el que no lo he investigado lo suficiente. Respaldarme Paul o Erland, LOL, ¿qué pasa con esto?
Eric Swiggum
@EricSwiggum 1) No necesitaría correr gritando si cambia el valor predeterminado de nivel de instancia. 2) Solo necesitaría promover la ausencia de ARITHABORT OFF si encuentra alguna incidencia real de la misma. Hasta ahora probablemente no haya ninguno. 3) Dado que esto afecta los planes de consulta, podría ser que las tablas nunca tuvieran suficientes datos para hacer que SQL Server tenga ciertas opciones a considerar, donde ahora hay más opciones y algunas son malas. O tal vez hay otros factores transitorios, como estadísticas desactualizadas, etc. No estoy completamente seguro.
Solomon Rutzky
@EricSwiggum No estoy en desacuerdo contigo allí. Creo que esto es muy similar a lo que mencioné al comienzo de mi respuesta (es decir, la clasificación predeterminada para los sistemas de inglés de EE. UU.): El temor de Microsoft a que los sistemas heredados obtengan errores al actualizar (es decir, la garantía de compatibilidad con versiones anteriores) hace más daño que bien, ya que en realidad aumenta la base de instalación / alcance del escenario no ideal. Esto hace que sea una atracción cada vez mayor permanecer en el pasado y una posibilidad cada vez menor de que las cosas mejoren. Estos son casos en los que es mejor arrancar la curita y simplemente superar el dolor ahora.
Solomon Rutzky