¿Por qué SET ARITHABORT ON aceleraría drásticamente una consulta?

La consulta es una única selección que contiene muchos niveles de agrupación y operaciones de agregación. Con SET ARITHABORT ON se tarda menos de un segundo; de lo contrario, se tarda varios minutos. Hemos visto este comportamiento en SQL Server 2000 y 2008.

Respuesta

Un poco anticuado, pero para cualquiera que termine aquí con un problema similar …

Tuve el mismo problema. Para mí resultó ser el rastreo de parámetros, que al principio no entendía lo suficiente como para preocuparme. Agregué un «set arithabort on» que solucionó el problema, pero luego volvió. Luego leí:

http://www.sommarskog.se/query-plan-mysteries.html

Se aclaró -todo-. Porque estaba usando Linq para SQL y tenía opciones limitadas para solucionar el problema, terminé usando una guía de plan de consulta (ver el final del enlace) para forzar el plan de consulta que quería.

Comentarios

  • Más de seis años después, el vínculo proporcionado en esta respuesta sigue siendo » lectura obligatoria » … y aún actual también, la última revisión es de diciembre ‘ 17.

Respuesta

Las aplicaciones .NET se conectan con la opción deshabilitada de forma predeterminada, pero está habilitada de forma predeterminada en Management Studio. El resultado es que el servidor almacena en caché 2 planes de ejecución separados para la mayoría / todos los procedimientos. Esto afecta la forma en que el servidor realiza cálculos numéricos y, como tal, puede obtener resultados muy diferentes según el procedimiento. Esta es realmente solo una de las 2 formas comunes en las que un proc puede alimentarse con un plan de ejecución terrible, la otra es el rastreo de parámetros.

Eche un vistazo a https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance.aspx para un poco más de discusión al respecto.

Comentarios

  • Estoy de acuerdo con la mitad de esta respuesta. ¡Sin embargo, soy muy escéptico sobre la afirmación del cálculo numérico!
  • @Martin: Creo que no estaba claro. Solo estaba diciendo que ARITHABORT ON hace que SQL Server genere un error en cualquier div / 0 o error de desbordamiento aritmético. Cuando está apagado, sigue funcionando y por cualquier razón puede causar todo tipo de problemas horribles.
  • @Ben – Sí, lo siento, no ‘ no quería atacar particularmente su respuesta Solo estaba señalando que sería muy fácil cambiar una opción SET, obtener un plan mejor y diagnosticar erróneamente que es la opción en sí misma que tiene la culpa. ‘ no estoy convencido de que el tipo en tu enlace no ‘ haya hecho esto.
  • @Martin – No es un problema, no ‘ creía que me estabas atacando. La otra discusión que vinculé podría ser un poco confusa. Solo estaba tratando de brindar evidencia de apoyo.
  • @Martin En retrospectiva, creo que tiene razón.

Responder

Yo diría que es casi seguro que se trata de un rastreo de parámetros.

A menudo se afirma que SET OPTIONS puede afectar el rendimiento de esta manera, pero todavía no he visto una sola fuente autorizada para esta afirmación, excepto en el caso en el que usted está usando Vistas indexadas / columnas calculadas persistentes.

En este caso (para SQL2005 + y a menos que su base de datos esté en modo de compatibilidad SQL2000 ). Si tiene ARITHABORT y ANSI_WARNINGS OFF, verá que el índice no se está utilizando por lo que puede tener un escaneo en lugar de la búsqueda deseada (y algunos gastos generales ya que el resultado del cálculo persistente no se puede usar). ADO.NET parece tener por defecto ANSI_WARNINGS ON de una prueba rápida que acabo de hacer.

La afirmación en La respuesta de Ben de que «la forma en que el servidor realiza los cálculos numéricos» puede agregar minutos a un resultado que de otra manera tomaría menos de un segundo, simplemente no me parece creíble. Creo que lo que suele suceder es que, al investigar un problema de rendimiento, se utiliza Profiler para identificar la consulta infractora. Esto se pega en el estudio de administración y se ejecuta y devuelve los resultados al instante. La única diferencia aparente entre las conexiones es la opción ARITH_ABORT.

Una prueba rápida en una ventana de Management Studio muestra que cuando SET ARITHABORT OFF se enciende y se ejecuta la consulta, el problema de rendimiento se repite, por lo que aparentemente se cierra el caso. De hecho, esta parece ser la metodología de resolución de problemas utilizada en el enlace Gregg Stark .

Sin embargo, eso ignora el hecho de que con ese conjunto de opciones puedes terminan obteniendo exactamente el mismo plan incorrecto del caché .

Esta reutilización del plan puede ocurrir incluso si ha iniciado sesión como un usuario diferente al que usa la conexión de la aplicación.

Probé esto ejecutando una consulta de prueba primero desde una aplicación web y luego desde Management Studio con SET ARITHABORT OFF y pude ver que los recuentos de usuarios subían desde la siguiente consulta.

SELECT usecounts, cacheobjtype, objtype, text ,query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle) 

Para que este intercambio de planes de pf ocurra realmente, todas las claves de caché del plan deben ser iguales. Además del arithabort en sí, algunos otros ejemplos son que los usuarios en ejecución necesitan el mismo esquema predeterminado (si la consulta se basa en la resolución de nombres implícita) y las conexiones necesitan el mismo language establecido.

Una lista más completa de claves de caché del plan aquí

Respuesta

Sé que llego tarde a esta fiesta, pero para los futuros visitantes, Martin tiene toda la razón. Nos encontramos con el mismo problema: un SP funcionaba muy lentamente para clientes .NET, mientras que para SSMS fue increíblemente rápido. Al explorar y resolver el problema, hicimos las pruebas sistemáticas que Kenny Evitt pregunta en su comentario a la pregunta de Martin.

Usando una variante de En la consulta de Martin, busqué el SP en el caché del procedimiento y encontré dos de ellos. Mirando los planos, era de hecho el caso de que uno tenía ARITHABORT ON y otro tenía ARITHABORT OFF. La versión ARITHABORT OFF tenía un índice de búsqueda mientras que la versión ARITHABORT ON utilizó un escaneo de índice para esa misma salida. Dados los parámetros involucrados, la búsqueda de índice habría requerido una búsqueda en decenas de millones de registros para la salida.

Borré los dos procedimientos de la caché e hice que el cliente .NET ejecutara el SP nuevamente, usando los mismos parámetros (que presentaban un amplio rango de fechas para un cliente con mucha actividad). El SP regresó instantáneamente. El plan almacenado en caché usó el mismo escaneo de índice que se presentó anteriormente en el plan ARITHABORT ON, pero esta vez el plan fue para ARITHABORT OFF. Ejecutamos el SP con los mismos parámetros en SSMS y nuevamente obtuvimos resultados al instante. Ahora vimos que se almacenó en caché un segundo plan, para ARITHABORT ON, con el escaneo de índice.

Luego borramos la caché, ejecutamos el SP en SSMS con un rango de fechas estrecho y obtuvimos un resultado instantáneo. Descubrimos que el plan almacenado en caché resultante tenía una búsqueda de índice, ya que la misma salida se manejó previamente con un escaneo (que también era una búsqueda en el plan original con ARITHABORT OFF). Nuevamente desde SSMS, ejecutamos el SP, esta vez con el mismo rango de fechas amplio, y vimos el mismo rendimiento terrible que tuvimos en la solicitud .NET original.

En resumen, la disparidad no tuvo nada que ver con el valor real de ARITHABORT – con él activado o desactivado, de cualquier cliente, podríamos obtener un rendimiento aceptable o terrible: todo lo que importaba eran los valores de los parámetros utilizados para compilar y almacenar en caché el plan.

Mientras MSDN indica que ARITHABORT OFF en sí mismo puede tener un impacto negativo en la optimización de consultas, nuestras pruebas confirman que Martin está en lo correcto: la causa fue el rastreo de parámetros y el plan resultante no es óptimo para todos los rangos de parámetros.

Comentarios

  • Me pregunto qué significa esa frase Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.. Ya sea que solo estén hablando de la imposibilidad de usar índices en columnas y vistas calculadas (si ANSI_WARNINGS también está desactivado) o si de hecho tiene algún otro efecto.
  • ‘ no estoy seguro. Me pregunto si ‘ es simplemente el caso de que alguien en MSDN se encontró con una situación similar, configuró ARTIHABORT en ON, vio la mejora en el rendimiento y llegó a las mismas conclusiones que otros. En cuanto a las vistas indexadas y las columnas calculadas, ‘ no estoy claro. En un momento, establece que las opciones SET deben tener valores específicos si una operación INSERT, UPDATE o DELETE modifica los valores de datos almacenados allí. En otra parte afirman que el optimizador ignorará los índices de » cualquier consulta » que haga referencia a dicha vista indexada o columna calculada. ¿Ambos son verdaderos, o es realmente » alguna consulta que modifica datos «?

Respuesta

Acabo de tener este problema. Como dijo la gente aquí, la causa principal son los planes de consultas múltiples, uno de los cuales no es óptimo. Solo quería verificar que ARITHABORT puede causar el problema por sí solo (ya que la consulta con la que estaba teniendo problemas no tenía parámetros, lo que elimina la detección de parámetros de la ecuación).

Respuesta

Esto me recuerda exactamente el mismo problema que experimenté en sql server 2008 days. En nuestro caso, de repente encontramos que un trabajo sql se ralentizó repentinamente (generalmente unos segundos, y ahora más de 9 minutos), el trabajo necesita acceder a un servidor vinculado, agregamos set ARITHABORT on en el paso del trabajo, y parecía el problema se resolvió durante unos días y luego regresó.

Más tarde abrimos un ticket con el soporte de MS, y al principio tampoco pudieron averiguarlo, y el ticket se escaló a un equipo de PFE muy senior, y dos Las empresas de apoyo a las empresas intentaron resolver este problema.

La razón final es que la credencial de usuario (para ejecutar el paso del trabajo) no puede acceder a las estadísticas de las tablas subyacentes (en el lado del servidor vinculado) y, por lo tanto, el plan de ejecución no está optimizado.

En detalle, el usuario no tiene permiso en DBCC SHOW_STATISTICS (aunque el usuario puede SELECCIONAR de la mesa). De acuerdo con MSDN , esta regla de permiso se cambia después de sql 2012 SP1

Permisos para SQL Server y Base de datos SQL

Para ver el objeto de estadísticas, el usuario debe ser propietario de la tabla o el usuario debe ser miembro de la función fija de servidor sysadmin, la función fija de base de datos db_owner o la función fija de base de datos db_ddladmin.

SQL Server 2012 SP1 modifica las restricciones de permisos y permite a los usuarios con permiso SELECT utilizar este comando. Tenga en cuenta que existen los siguientes requisitos para que los permisos SELECT sean suficientes para ejecutar el comando:

Para verificar este problema, solo necesitamos ejecutar el generador de perfiles en la instancia del lado del servidor vinculado y activar algunos eventos en «Errores y advertencias «como se muestra a continuación.

ingrese la descripción de la imagen aquí

Espero que esta experiencia pueda ayudar a la comunidad de alguna manera.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *