¿Por qué SET ARITHABORT ON aceleraría dramáticamente una consulta?

75

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

Jonathan Allen
fuente

Respuestas:

62

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

Yo tuve el mismo problema. Para mí resultó ser la detección de parámetros, que al principio no entendí lo suficiente como para preocuparme. Agregué un 'set arithabort on' que solucionó el problema pero luego regresó. Entonces leí:

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

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


fuente
3
Más de seis años después, el enlace que figura en esta respuesta sigue siendo "lectura obligatoria" ... y todavía actual, la última revisión es diciembre '17.
takrl
30

Las aplicaciones .NET se conectan con la opción deshabilitada de manera predeterminada, pero está habilitada de manera predeterminada en Management Studio. El resultado es que el servidor realmente 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 que un proceso puede alimentarse de un plan de ejecución terrible, el otro es la detección 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.

Ben Hoffman
fuente
Estoy de acuerdo con la mitad de esta respuesta. Sin embargo, soy muy escéptico sobre la afirmación de cálculo numérico.
Martin Smith
2
@ Martin: Creo que no estaba claro. Solo decía que ARITHABORT ON hace que SQL Server produzca un error en cualquier div / 0 o error de desbordamiento aritmético. Cuando está apagado, continúa y, por cualquier motivo, puede causar todo tipo de problemas horribles.
@Ben: sí, lo siento, no quería atacar particularmente tu respuesta, solo estaba señalando que sería muy fácil cambiar una SETopción, obtener un mejor plan y diagnosticar erróneamente que esta es la Opción en sí. No estoy convencido de que el tipo en tu enlace no haya hecho esto.
Martin Smith
@ Martin - No hay problema, no pensé que me estuvieras atacando. La otra discusión que vinculé podría ser un poco confusa. Solo estaba tratando de dar evidencia de apoyo.
@Martin En retrospectiva, creo que tienes razón.
21

Yo diría que esto es casi seguro que olfateó los parámetros.

A menudo se afirma que SET OPTIONSpuede afectar el rendimiento de esta manera, pero aún no he visto una única fuente autorizada para este reclamo, excepto en el caso de que esté utilizando 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 ambos ARITHABORTy ANSI_WARNINGS OFFluego encontrará que el índice no se está utilizando, 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 ONuna 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 otro modo 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 de rendimiento, Profiler se utiliza para identificar la consulta ofensiva. Esto se pega en el estudio de gestión y se ejecuta y devuelve resultados al instante. La única diferencia aparente entre las conexiones es la ARITH_ABORTopción.

Una prueba rápida en una ventana del estudio de administración muestra que cuando SET ARITHABORT OFFse activa 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 solución de problemas utilizada en el enlace Gregg Stark .

Sin embargo, eso ignora el hecho de que con esa opción establecida, puede terminar 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 el estudio de administración con SET ARITHABORT OFFy pude ver los conteos de uso que suben de la consulta a continuación.

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 plan compartido pueda ocurrir, todas las claves de caché del plan deben ser las mismas. Además de arithabortotros ejemplos, los usuarios que ejecutan necesitan el mismo esquema predeterminado (si la consulta se basa en una resolución de nombre implícita) y las conexiones necesitan el mismo languageconjunto.

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

Martin Smith
fuente
13

Sé que llego tarde a esta fiesta, pero para futuros visitantes, Martin es exactamente correcto. Nos encontramos con este mismo problema: un SP se estaba ejecutando muy lentamente para los clientes .NET, mientras que era extremadamente rápido para SSMS. Al explorar y resolver el problema, hicimos las pruebas sistemáticas sobre las que Kenny Evitt pregunta en su comentario a la pregunta de Martin.

Usando una variante de la consulta de Martin, busqué el SP en el caché de procedimientos y encontré dos de ellos. Mirando los planes, de hecho, uno tenía ARITHABORT ENCENDIDO y uno tenía ARITHABORT APAGADO. La versión ARITHABORT OFF tenía una búsqueda de índice, mientras que la versión ARITHABORT ON utilizaba una exploración de índice para esa misma salida. Dados los parámetros involucrados, la búsqueda del índice habría requerido una búsqueda en decenas de millones de registros para la salida.

Eliminé los dos procedimientos del 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ó al instante. El plan en caché utilizaba el mismo escaneo de índice que aparecía anteriormente en el plan ARITHABORT ON, pero esta vez el plan era 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 el caché, ejecutamos el SP en SSMS con un rango de fechas estrecho y obtuvimos un resultado instantáneo. Descubrimos que el plan en caché resultante tenía una búsqueda de índice, ya que la misma salida se manejó previamente con un escaneo (que también fue una búsqueda en el plan original con ARITHABORT OFF). Nuevamente desde SSMS, ejecutamos el SP, esta vez con el mismo amplio rango de fechas, y vimos el mismo desempeño terrible que tuvimos en la solicitud original de .NET.

En resumen, la disparidad no tenía nada que ver con el valor real de ARITHABORT: con él activado o desactivado, desde cualquier cliente, podíamos obtener un rendimiento aceptable o terrible: todo lo que importaba eran los valores de los parámetros utilizados en la compilación y el almacenamiento en caché del plan.

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

mdoyle
fuente
1
Me pregunto qué Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.significa esa frase . Ya sea que solo estén hablando de la incapacidad de usar índices en columnas y vistas calculadas (si ANSI_WARNINGStambién está desactivado) o si realmente tiene algún otro efecto.
Martin Smith
No estoy seguro. Me pregunto si es simplemente el caso de que alguien en MSDN se topó con una situación similar, puso ARTIHABORT en ON, vio la mejora del 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 en ellos. En otro lugar, afirman que el optimizador ignorará los índices para "cualquier consulta" que haga referencia a dicha vista indexada o columna calculada. ¿Son ambos verdaderos, o es realmente "cualquier consulta que modifique datos"?
mdoyle
1

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

Alan D. Nelson
fuente
1

Esto me recuerda exactamente el mismo problema que experimenté en el servidor SQL 2008 días. 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 ARITHABORT activado en el paso del trabajo, y parecía que el problema era fue resuelto por unos días y luego regresó.

Más tarde abrimos un ticket con soporte de MS, y al principio tampoco pueden descubrirlo, y el ticket se escaló a un equipo de PFE muy importante, y dos PFE de soporte intentaron resolver este problema.

La razón final es que la credencial de usuario (para ejecutar el paso de 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 tabla). Según MSDN , esta regla de permiso 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 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 usar 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 la sección "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.

jyao
fuente