La consulta se agota desde la aplicación web pero funciona bien desde el estudio de administración

StackOverflow https://stackoverflow.com/questions/9974

  •  08-06-2019
  •  | 
  •  

Pregunta

Esta es una pregunta que hice en otro foro que recibió algunas respuestas decentes, pero quería ver si alguien aquí tiene más información.

El problema es que una de sus páginas en una aplicación web agota el tiempo de espera cuando llega a una llamada a un procedimiento almacenado, por lo que usa Sql Profiler, o los registros de seguimiento de su aplicación, para encontrar la consulta y la pega en Management Studio para calcularla. Nuestro por qué está funcionando lento.Pero lo ejecutas desde allí y simplemente avanza, regresando en menos de un segundo cada vez.

Mi caso particular fue usar ASP.NET 2.0 y Sql Server 2005, pero creo que el problema podría aplicarse a cualquier sistema RDBMS.

¿Fue útil?

Solución

Esto es lo que he aprendido hasta ahora de mi investigación.

.NET envía configuraciones de conexión que no son las mismas que las que obtiene cuando inicia sesión en Management Studio.Esto es lo que ve si huele la conexión con Sql Profiler:

-- network protocol: TCP/IP  
set quoted_identifier off  
set arithabort off  
set numeric_roundabort off  
set ansi_warnings on  
set ansi_padding on  
set ansi_nulls off  
set concat_null_yields_null on  
set cursor_close_on_commit off  
set implicit_transactions off  
set language us_english  
set dateformat mdy  
set datefirst 7  
set transaction isolation level read committed  

Ahora estoy pegando esa configuración encima de cada consulta que ejecuto cuando inicio sesión en el servidor SQL, para asegurarme de que la configuración sea la misma.

Para este caso, probé cada configuración individualmente, después de desconectarme y volver a conectarme, y descubrí que cambiar arithabort de desactivado a activado redujo la consulta del problema de 90 segundos a 1 segundo.

La explicación más probable está relacionada con la detección de parámetros, que es una técnica que utiliza Sql Server para elegir lo que cree que es el plan de consulta más eficaz.Cuando cambia una de las configuraciones de conexión, el optimizador de consultas puede elegir un plan diferente y, en este caso, aparentemente eligió uno malo.

Pero no estoy totalmente convencido de esto.Intenté comparar los planes de consulta reales después de cambiar esta configuración y todavía no he visto que la diferencia muestre ningún cambio.

¿Hay algo más en la configuración de arithabort que pueda hacer que una consulta se ejecute lentamente en algunos casos?

La solución parecía sencilla:Simplemente coloque set arithabort en la parte superior del procedimiento almacenado.Pero esto podría llevar al problema opuesto:cambie los parámetros de consulta y de repente se ejecuta más rápido con "apagado" que con "encendido".

Por el momento estoy ejecutando el procedimiento 'con recompilación' para asegurarme de que el plan se regenere cada vez.Está bien para este informe en particular, ya que puede tardar un segundo en volver a compilarse, y esto no se nota demasiado en un informe que tarda entre 1 y 10 segundos en regresar (es un monstruo).

Pero no es una opción para otras consultas que se ejecutan con mucha más frecuencia y deben regresar lo más rápido posible, en solo unos pocos milisegundos.

Otros consejos

He tenido problemas similares.Intente configurar la opción "CON RECOMPILAR" en la creación de sproc para forzar al sistema a recalcular el plan de ejecución cada vez que se llama.A veces, el procesador de consultas se confunde con procedimientos almacenados complejos con muchas ramificaciones o declaraciones de casos y simplemente elabora un plan de ejecución realmente subóptimo.Si eso parece "solucionar" el problema, probablemente necesitará verificar que las estadísticas estén actualizadas y/o desglosar el sproc.

También puedes confirmar esto perfilando el sproc.Cuando lo ejecuta desde SQL Managment Studio, ¿cómo se compara el IO con cuando lo perfila desde la aplicación ASP.NET?Si lo hacen mucho, simplemente refuerza el hecho de que está ejecutando un mal plan de ejecución.

¿Ya ha activado el seguimiento de ASP.NET?Tuve un caso en el que el problema no era el procedimiento almacenado de SQL en sí, sino el hecho de que el procedimiento devolvió 5000 filas y la aplicación intentaba crear ListItems vinculados a datos con esos 5000 elementos lo que estaba causando el problema.

También puede consultar los tiempos de ejecución entre las funciones de la aplicación web a través del seguimiento para ayudar a rastrear las cosas.

Pruebe esto primero en un cuadro de prueba, cámbielo a nivel de servidor para el servidor SQL

declarar @opción int

set @Option = @@ Opciones | 64

Ejec sp_configure 'Opciones de usuario', @Option

RECONFIGURAR

El mismo problema que tuve con los servicios de informes SQL.Intente verificar el tipo de variables, estaba enviando diferentes tipos de variables a SQL, como enviar a Varchar en su lugar donde debería ser entero, o algo así.Después de sincronizar los tipos de variables en Reporting Service y en el procedimiento almacenado en SQL, resolví el problema.

Podrías intentar usar el comando sp_who2 para ver qué proceso en cuestión está haciendo.Esto le mostrará si está bloqueado por otro proceso o si está consumiendo una cantidad excesiva de CPU y/o tiempo de IO.

Tuvimos el mismo problema y esto es lo que descubrimos.

El tamaño de registro de nuestra base de datos se mantuvo en el valor predeterminado (814 MB) y el crecimiento automático fue del 10%.En el servidor, la memoria máxima del servidor también se mantuvo en la configuración predeterminada (2147483647 MB).

Cuando nuestro registro se llenó y necesitó crecer, usó toda la memoria del servidor y no quedó nada para ejecutar el código, por lo que se agotó el tiempo de espera.Lo que terminamos haciendo fue establecer el tamaño inicial del archivo de registro de la base de datos en 1 MB y la memoria máxima del servidor en 2048 MB.Esto solucionó instantáneamente nuestro problema.Por supuesto, puede cambiar estas dos propiedades para adaptarlas a sus necesidades, pero esta es una idea para alguien que se encuentra con el problema del tiempo de espera al ejecutar un procedimiento almacenado mediante código, pero se ejecuta súper rápido en SSMS y las soluciones anteriores no ayudan.

Intente cambiar el valor de tiempo de espera de SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top