Máquinas idénticas (?) SQL Server 2005; la consulta toma 2 segundos en uno, 15 minutos en el otro

12

El entorno:

Tenemos dos máquinas Windows Server 2003 R2 de 32 bits que ejecutan SQL Server 2005. Las configuraciones de hardware son servidores idénticos con CPU Xeon 5160, 4 GB de RAM y 13 GB de RAID0. Las banderas AWE y / 3GB no están habilitadas.

Los servidores se configuraron uno al lado del otro utilizando una lista de verificación de instalación predefinida, y TODO el software instalado es el mismo en ambas máquinas.

Cada configuración de instalación del servidor SQL y nivel de parche que sabemos verificar son idénticos. Una diferencia es que TEMPDB es de 400 MB en la máquina rápida y de 1,2 GB en la máquina lenta. Sin embargo, en ambos casos, no vemos ninguna asignación TEMPDB.

El problema:

Hay un procedimiento almacenado que se ejecuta en 2 segundos en uno, pero 15 minutos en el otro. Durante los 15 minutos adicionales, hay poca o ninguna actividad en el disco, no hay cambios en el uso de la memoria, pero un núcleo de CPU se fija al 100% todo el tiempo.

Este comportamiento persiste incluso cuando las bases de datos se respaldan de una y se restauran a la otra.

Dado que se trata de un procedimiento almacenado, el monitor de actividad y el generador de perfiles no nos muestran ningún detalle sobre en qué parte del procedimiento almacenado está teniendo lugar esta alta actividad de la CPU.

La pregunta:

¿Qué más deberíamos estar mirando?

Seguimiento:

La lentitud ocurre en las instrucciones FETCH NEXT para la siguiente definición de cursor:

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE X NOT IN (SELECT X FROM dbo.B)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...

Cada una de las declaraciones FETCH, en una tabla que contiene solo alrededor de 1000 filas, requiere aproximadamente 7.25 minutos. (No, no sé por qué hace dos seguidas, necesito preguntar a los desarrolladores, pero se ejecuta correctamente en ambos servidores).

Sospecho un poco de que "NO ES (SELECCIONE ...)", ya que parece que las lecturas virtuales son realmente altas.

ryandenki
fuente
¿Cómo se pueden registrar en dbo.B y se indexa dbo.BX?
Mark Storey-Smith
1
Tengo curiosidad por saber si habría una diferencia de rendimiento si opta por esto: seleccione dbo.ax, dbo.ay desde dbo.a combinación externa izquierda dbo.b en dbo.ax = dbo.bx donde dbo.bx es nulo y z <= 0
DForck42
Un pensamiento más para tirar la mezcla. ¿Estás seguro de que la ralentización se debe a la búsqueda del cursor? ¿Está determinando esto a partir del plan de ejecución (que se trata de estimaciones) o de una traza de perfil?
Mark Storey-Smith
Es de un rastro de perfil.
ryandenki
¿Son iguales los planes de ejecución? Es posible que uno de ellos esté usando un mal plan de ejecución.
Zane

Respuestas:

7

Al utilizar una metodología de solución de problemas de rendimiento como Esperas y Colas, se identifica la razón del alto consumo de CPU, luego se puede recomendar la acción adecuada una vez que se identifica el cuello de botella.

Remus Rusanu
fuente
6

SQL Server está eligiendo un plan diferente en el otro cuadro.

La restauración generalmente eliminará los problemas basados ​​en las estadísticas, por lo que analizaría las diferencias del servidor.

Algunos cheques gruesos primero. No asumas: verifica

  • Compruebe que la configuración de SQL Server es la misma en sys.configuration, por ejemplo, Grado máximo o paralelismo
  • Ejecute DBCC USEROPTIONS para ver si alguna configuración ANSI es diferente en el tiempo de ejecución (la configuración ANS puede afectar el plan elegido)
  • Verifique los registros de Windows y SQL Server para ver si hay algún problema

Luego salta al fondo, según la respuesta de Remus.

gbn
fuente
Gracias por las pistas. Tanto sys.configurations como DBCC USEROPTIONS son idénticos entre las dos máquinas. No hay errores ni advertencias en ningún registro del servidor de Windows o SQL.
1
¿Y también ejecutan el diseño idéntico de la base de datos? ¿Ningún plan de administración realiza optimizaciones en (reconstrucción de índice, etc.), las bases de datos tienen las mismas estadísticas para objetos relevantes y el mismo diseño de disco? ¿El mismo nivel de parche?
TomTom
Sí, mismo disco, diseño de base de datos y nivel de parche. De hecho, la base de datos en la máquina rápida es una copia de seguridad restaurada de la máquina lenta. Y no hay planes de administración que varíen, por lo que puedo ver.
ryandenki
6

Si todas las demás cosas son iguales, es probable (según la respuesta de @ gbn) que se genere un plan de ejecución diferente en cada servidor. Como ejercicio académico, sería interesante ver ambos planes, así que tómalos del caché del plan en cada servidor y agrégalos a tu pregunta si es posible. Entonces podemos identificar las diferencias en los planes que están causando una variación tan grande en el rendimiento.

Para una solución rápida, eche un vistazo a la sugerencia USE PLAN . Esto permite adjuntar el buen plan desde el servidor rápido al procedimiento almacenado en el servidor lento.

Editar: Siguiente actualización re: cursor

Otra variación en su consulta para probar que no veo mencionado en otras respuestas:

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE NOT EXISTS (SELECT 1 FROM dbo.B WHERE dbo.B.X = dbo.A.X)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
Mark Storey-Smith
fuente
Este es un buen consejo, estamos revisando los planes de consulta. En realidad, la desaceleración en el procedimiento almacenado parece estar vinculada a un cursor. Ver editar.
ryandenki
4

Compláceme e intente reemplazar:

DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0

con este:

DECLARE C CURSOR FOR
SELECT 
    X, 
    Y
FROM dbo.A

    LEFT OUTER JOIN dbo.B
        ON dbo.A.X = dbo.b.X

WHERE dbo.B.X IS NULL
AND Z <=0

No creo que esto deba manifestarse como un problema de rendimiento en la parte FETCH NEXT FROM de su código, pero todavía no me han administrado la inyección de cafeína. Prueba mi sugerencia y avísame.

Espero que esto ayude,

Mate

Matt M
fuente
4

Verifique sus índices y actualice todas sus estadísticas. He tenido un problema muy simple y resultó que las estadísticas en una máquina eran inestables.

DForck42
fuente
1

He experimentado este mismo comportamiento dos veces y te diré qué lo solucionó cada vez:

1.) Agregué la sugerencia WITH RECOMPILE al procedimiento almacenado porque el plan en caché era terrible.

2.) Cambié el procedimiento almacenado para usar tablas temporales en lugar de variables de tabla.

Espero que cualquiera de esos ayude. Buena suerte.

Jon
fuente