v17 tutorial studio management activity actividad sql-server sql-server-2008 query-performance arithabort

sql-server - tutorial - ssms 16.5 3



La consulta se agota cuando se ejecuta desde la web, pero es superrápida cuando se ejecuta desde SSMS. (7)

Estoy intentando depurar el origen de un tiempo de espera de SQL en una aplicación web que mantengo. Tengo el código fuente del código C # detrás, así sé exactamente qué código se está ejecutando. He depurado la aplicación hasta la línea que ejecuta el código SQL que agota el tiempo de espera, y miro la consulta ejecutándose en SQL Profiler.

Cuando esta consulta se ejecuta desde la web, se agota después de 30 segundos. Sin embargo, cuando corté / pegué la consulta exactamente como se presentó en Profiler, y la puse en SSMS y la ejecuté, se devuelve casi al instante. He rastreado el problema hasta que ARITHABORT se configuró en OFF en la conexión que está usando la web (es decir, si desactivo ARITHABORT en la sesión SSMS, se ejecuta durante un tiempo prolongado, y si lo vuelvo a encender, se ejecuta). muy rápidamente). Sin embargo, al leer la descripción de ARITHABORT, no parece aplicarse ... Solo estoy haciendo un SELECCIONAMIENTO simple, y NO se está realizando ninguna aritmética en absoluto ... solo una UNIÓN INTERNA con una condición WHERE:

¿Por qué ARITHABORT OFF estaría causando este comportamiento en este contexto? ¿Hay alguna manera de que pueda modificar la configuración de ARITHABORT para esa conexión de SSMS? Estoy usando SQL Server 2008.


Entonces, ¿su código C # está enviando una consulta SQL ad hoc a SQL Server, usando qué método? ¿Has considerado usar un procedimiento almacenado? Eso probablemente garantizaría el mismo rendimiento (al menos en el motor) independientemente de quién lo haya llamado.

¿Por qué? La configuración de ARITHABORT es una de las cosas que el optimizador observa cuando determina cómo ejecutar su consulta (más específicamente, para la coincidencia de planes). Es posible que el plan en caché tenga la misma configuración que SSMS, por lo que usa el plan en caché, pero con la configuración opuesta, su código C # obliga a recompilar (o tal vez está golpeando un plan realmente MALO en el caché), que ciertamente puede perjudicar el rendimiento en muchos casos.

Si ya está llamando a un procedimiento almacenado (no publicó su consulta, aunque creo que tenía intención de hacerlo), puede intentar agregar OPCIÓN (RECOMPRA) a la consulta (o consultas) ofensivas en el procedimiento almacenado. Esto significará que esas declaraciones siempre se volverán a compilar, pero podría evitar el uso del plan malo al que parece estar atacando. Otra opción es asegurarse de que cuando se compila el procedimiento almacenado, el lote se ejecuta con SET ARITHABORT ON.

Finalmente, parece que se pregunta cómo puede cambiar la configuración de ARITHABORT en SSMS. Creo que lo que querías preguntar es cómo puedes forzar la configuración de ARITHABORT en tu código. Si decide continuar enviando SQL ad hoc desde su aplicación C #, entonces, por supuesto, puede enviar un comando como texto que tiene múltiples instrucciones separadas por punto y coma, por ejemplo:

SET ARITHABORT ON; SELECT ...

Para obtener más información sobre por qué ocurre este problema, consulte el gran artículo de Erland Sommarskog:


He tenido este problema muchas veces, pero si tiene un procedimiento almacenado con el mismo problema, al eliminar y volver a crear el proceso almacenado se resolverá el problema.

Se llama detección de parámetros. Necesita siempre localizar los parámetros en el proceso almacenado para evitar este problema en el futuro.

Entiendo que esto podría no ser lo que el póster original quiere, pero que podría ayudar a alguien con el mismo problema.


Si puede cambiar su código para corregir el parámetro sniffing, optimizar su sugerencia desconocida es su mejor opción. Si no puede cambiar su código, la mejor opción es exec sp_recompile ''name of proc'', que obligará solo a ese proceso almacenado a obtener un nuevo plan de ejecución. Dejar caer y volver a crear un proceso tendría un efecto similar, pero podría causar errores si alguien intenta ejecutar el proceso mientras lo tiene. DBCC FREEPROCCACHE descarta todos sus planes almacenados en caché, lo que puede causar estragos en su sistema e incluso causar muchos tiempos de espera en un entorno de producción de transacciones pesadas. Establecer arithabort no es una solución al problema, pero es una herramienta útil para descubrir si el olfateo de parámetros es el problema.


Si usa Entity Framework debe saber que los parámetros de consulta para los valores de cadena se envían a la base de datos como nvarchar, si la columna de base de datos para comparar es varchar, dependiendo de su intercalación PUEDE requerir una "CONVERSIÓN IMPLÍCITA" que evite los índices.

Finalmente lo descubrí gracias a este artículo: https://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-cause-index-scans/


Tengo el mismo problema al tratar de llamar a SP desde SMSS me tomó 2 segundos, mientras que desde la aplicación web (ASP.NET) me llevó unos 3 minutos.

Intenté todas las soluciones sugeridas sp_recompile , DBCC FREEPROCCACHE y DBCC DROPCLEANBUFFERS pero nada solucionó mi problema, pero cuando probé el parámetro sniffing, funcionó, y funcionó bien.


Tuve el mismo problema y se solucionó al ejecutar el procedimiento "WITH RECOMPILE". También puedes intentar usar el parámetro sniffing. Mi problema estaba relacionado con la caché de SQL.


Esta respuesta incluye una forma de resolver este problema:

Al ejecutar los siguientes comandos como administrador en la base de datos, todas las consultas se ejecutan como se espera, independientemente de la configuración de ARITHABORT.

DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE

Actualizar

Parece que la mayoría de la gente termina teniendo este problema muy pocas veces, y la técnica anterior es una corrección decente de una sola vez. Pero si una consulta específica presenta este problema más de una vez, una solución a más largo plazo para este problema sería utilizar sugerencias de consulta como OPTIMIZE FOR y OPTION(Recompile) , como se describe en este artículo .