SQL Server 2012 más lento que 2008

15

Migré un sitio web grande y una base de datos de un servidor anterior (Windows 2008 / SQL Server 2008/16 GB RAM / 2 x discos Quad Core / SAS de 2.5 GHz) a un servidor más nuevo y mucho mejor (Windows 2008 R2 / SQL Server 2012 SP1 / 64 GB de RAM / 2 x 2,1 GHz 16 procesadores de núcleo / discos SSD).

Separé los archivos de la base de datos en el servidor anterior, los copié y los adjunté en el nuevo servidor. Todo salió muy bien.

Después de eso, cambié al nivel de compatibilidad a 110, actualicé estadísticas, reconstruí índices.

Para mi gran decepción, noté que la mayoría de las consultas SQL son mucho más lentas (2-3-4 veces más lentas) en el nuevo servidor SQL 2012 que en el antiguo servidor SQL 2008.

Por ejemplo, en una tabla con alrededor de 700k registros, en el servidor anterior, una consulta sobre el índice tomaba alrededor de 100 ms. En el nuevo servidor, la misma consulta toma alrededor de 350 ms.

Lo mismo sucede para todas las consultas.

Agradecería un poco de ayuda aquí. Déjame saber qué verificar / verificar. Porque me resulta muy difícil creer que en un mejor servidor con un SQL Server más nuevo, el rendimiento sea peor.

Más detalles:

La memoria está configurada al máximo.

Tengo esta tabla e índice:

CREATE TABLE [dbo].[Answer_Details_23](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NOT NULL,
    [SurveyID] [int] NOT NULL,
    [CustomerID] [int] NOT NULL default 0,
    [SummaryID] [int] NOT NULL,
    [QuestionID] [int] NOT NULL,
    [RowID] [int] NOT NULL default 0,
    [OptionID] [int] NOT NULL default 0,
    [EnteredText] [ntext] NULL,
 CONSTRAINT [Answer_Details_23_PK] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_Answer_Details_23_SummaryID_QuestionID] ON [dbo].[Answer_Details_23]
(
    [SummaryID] ASC,
    [QuestionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Ejecuté esta consulta:

set statistics time on;
select summaryid, count(summaryid) from Answer_Details_23 group by summaryid order by count(summaryid) desc;
set statistics time off;

SERVIDOR ANTIGUO - Tiempos de ejecución del servidor SQL: tiempo de CPU = 419 ms, tiempo transcurrido = 695 ms.

NUEVO SERVIDOR - Tiempos de ejecución de SQL Server: tiempo de CPU = 1340 ms, tiempo transcurrido = 1636 ms.

PLANES DE EJECUCIÓN cargados aquí: http://we.tl/ARbPuvf9t8

Actualización posterior:

  • Los procesadores AMD 2.1GHz Opteron 16 core se ven mucho peor que los procesadores Intel quad core 2.5GHz
  • Gran mejora al cambiar las opciones de energía de Windows de balanceada a alta potencia
  • Mejora adicional cambiando el grado máximo de paralelismo a 8 y el umbral de costo a 4

Ahora, tiempos de ejecución de SQL Server: tiempo de CPU = 550 ms, tiempo transcurrido = 828 ms.

Todavía es peor que el antiguo servidor, pero no está tan mal. Si tiene otras sugerencias (que no sean optimizaciones de consultas locales), no dude en comentar.

prog_sr08
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Paul White reinstala a Monica

Respuestas:

8

He tenido problemas similares con SQL Server, es posible que su servidor no esté configurado de manera óptima. Los Xeons más nuevos vienen con TurboBoost, HT, etc., que pueden afectar significativamente el rendimiento del servidor.

Por ejemplo, hemos tenido éxito con; Configuración de baja latencia para servidores Dell

La configuración será aplicable a los servidores que no son de Dell, solo pueden tener nombres diferentes.

También mejoramos el rendimiento al configurar el perfil de administración de energía de Windows en alto rendimiento, desde Balanced. Una pieza final es que se recomienda reservar hasta 8 GB de memoria para el sistema operativo en servidores x64, la instalación SQL predeterminada toma toda la memoria. Es posible que desee probar la reserva de 4 / 8GB configurando la configuración de memoria máxima de SQL Server en 4 / 8GB menos que la memoria total.

Mi recomendación sería volver al antiguo servidor si es posible. Si no tiene scripts de regresión / automatización / carga disponibles, lo mejor que puede hacer es registrar la actividad de su sistema durante 1-4 horas durante un período de alta actividad. Luego configure un servidor web igual que producción y una máquina cliente para ejecutar el script. Ejecute la misma actividad en el nuevo servidor, realice el cambio de configuración y vuelva a ejecutar la misma actividad. Realmente querrás hacer mucho más, pero no parece que sea viable y está fuera del alcance de esta pregunta.

AceCTO
fuente
La carga no es tan alta en el servidor. SQL Server generalmente se encuentra en 20-35 GB de memoria. En cualquier momento teníamos más de 16 GB de memoria libre. Además, el procesador no suele pasar del 10 al 15% de uso.
prog_sr08
2
La mejoría más grande lograda hasta ahora al configurar la administración de energía de Windows de energía equilibrada a alta. Entonces realmente parece un problema de procesador. Tiempos de ejecución de SQL Server: tiempo de CPU = 892 ms, tiempo transcurrido = 874 ms.
prog_sr08
8

Déjame saber qué verificar / verificar

Tienes un problema de rendimiento. Siga una metodología de solución de problemas de rendimiento como esperas y colas para identificar el cuello de botella. La metodología vinculada muestra qué medir y cómo. Publique aquí los resultados y podemos ayudarlo con consejos específicos basados ​​en sus mediciones reales. Como está es demasiado abierto y nadie lo sabe. Reducirlo a un problema específico eliminará las conjeturas.

Después de la actualización

Los planes son bastante diferentes. El plan anterior tenía un agregado de flujo bajo en la pila que en realidad tiene una mala estimación de cardinalidad (141k frente a 108k) y las matemáticas de hash predicen aún más erróneamente, a la inversa (35k frente a 108k). El nuevo plan no tiene el agregado de flujo y tiene estimaciones precisas hasta la cima. Por supuesto, esto no explica por qué el antiguo plan se estaba ejecutando más rápido .

Los escaneos inferiores tienen un número de fila ligeramente diferente (no significativo) pero costos bastante diferentes: el antiguo es 2.49884 (IO 2.28979 CPU 0.20905) frente al nuevo 1.59109 (IO 1.53868 CPU 0.0524084). Una vez más apuntaría hacia una mejor ejecución en 2012 (¿la reconstrucción del índice quizás haya reducido la fragmentación?).

Lo que es muy diferente es el número de subprocesos: 32 en nuevos (cada uno con ~ 23k filas) frente a 8 en viejos (cada uno con ~ 95k filas). La mesa es bastante estrecha. Que podría ser que el gran número de hilos es en realidad perjudicando el rendimiento debido a la mucho más frecuente invalidación de caché . Lo intentaré:

  1. eliminar HyperThreading en la nueva configuración del servidor (si existe) y / o
  2. intente la consulta con un DOP 8.

Noté tu comentario:

El plan de ejecución agregado con maxdop 8 Query es realmente más rápido de esta manera

Probablemente se trata solo de CPU que se pisan entre sí. Con los SSD en su lugar, el IO probablemente no sea casi nada, y la tabla es definitivamente demasiado pequeña para garantizar 32 escáneres. Ese intercambio de intercambio probablemente invalida L1 / L2 constantemente.

Remus Rusanu
fuente
1
Todo es mucho más lento en 2012 que en 2008. No estoy tratando de optimizar las consultas aquí. Me encantaría tener al menos el mismo rendimiento con la misma base de datos en este nuevo servidor.
prog_sr08
1
Esperas y colas no se trata de optimizar consultas. Se trata de identificar cuellos de botella.
Remus Rusanu
Descargué el documento. Se ve muy interesante. Estoy en eso ahora, pero parece que me llevará un tiempo. ¿Puedes sugerir dónde buscar primero?
prog_sr08
1
Estadísticas de espera . reinícielos en 2008 y 2012, ejecute la carga durante 5-10 minutos en ambos, luego compare las diferencias entre 2008 y 2012.
Remus Rusanu
Me temo que no puedo comparar las estadísticas entre los 2 servidores ahora, porque el nuevo servidor aloja un sitio / base de datos en vivo. En el antiguo servidor permaneció la base de datos que ya no está bajo carga.
prog_sr08
3

Para la mayoría de los sistemas multi-core modernos, y particularmente los sistemas multi-cpu, la arquitectura de hardware es tal que ciertas porciones de memoria están lejos de ciertos núcleos / procesadores, y ciertas porciones de memoria están cerca de ciertos núcleos / procesadores. Esto se conoce como arquitectura de memoria no uniforme o NUMA para abreviar. Desea que su configuración MAXDOP coincida con la cantidad de núcleos por nodo NUMA para minimizar la cantidad de veces que un nodo numa determinado debe salir de su propia memoria para datos.

Puede usar lo siguiente para verificar la configuración de su nueva máquina y asegurarse de que MAXDOP esté configurado con la mejor configuración, en cuanto a hardware :

DECLARE @CPUs int;
DECLARE @NumaNodes int;
DECLARE @ServerRAMInMB int;

SET @ServerRAMinMB = (SELECT (i.physical_memory_kb / 1024) AS ServerMemory 
    FROM sys.dm_os_sys_info i);
SET @CPUs = (SELECT i.cpu_count from sys.dm_os_sys_info i);
SET @NumaNodes = (SELECT MAX(c.memory_node_id) + 1 FROM sys.dm_os_memory_clerks c 
    WHERE memory_node_id < 64);

SELECT @ServerRamInMB, @CPUs, @NumaNodes;

IF @CPUs > 4 /* this would be 4 cores, not 4 CPUs */
BEGIN
    DECLARE @MaxDOP int;
    SET @MaxDOP = @CPUs * 0.75;
    IF @MaxDOP > (@CPUs / @NumaNodes) SET @MaxDOP = (@CPUs / @NumaNodes);
    EXEC sp_configure 'max degree of parallelism', @MaxDOP;
    EXEC sp_configure 'cost threshold for parallelism', 4; 
END

Incluí el @ServerRamInMBparámetro aquí desde que lo uso para la configuración Max Server Memoryy Min Server Memorylas opciones de configuración a los valores que sean apropiados para el servidor dado.

Max Vernon
fuente
1
Tengo 64 GB de RAM, 32 núcleos de procesador, 4 nodos numa. Establecí el grado máximo de paralelismo en 8 y el umbral de costo en 4. Con esta configuración y con la opción de energía configurada en alta potencia, Tiempos de ejecución de SQL Server: tiempo de CPU = 550 ms, tiempo transcurrido = 828 ms.
prog_sr08
Entonces, ¿eso es una victoria? ¡Me alegra ver que eso funciona para ti!
Max Vernon
0

¿En qué edición y modo de licencia estás? Probablemente no estés usando todos los núcleos. Véase la nota en esta página - http://msdn.microsoft.com/en-us/library/ms143760.aspx

"Las licencias basadas en Enterprise Edition con Server + Client Access License (CAL) están limitadas a un máximo de 20 núcleos por instancia de SQL Server".

Jeff Sacksteder
fuente
2
Esto solo se aplicaría si tuvo CAL antes y fue abonado. Aún con solo 20 núcleos, el rendimiento no debería caer notablemente sobre el sistema anterior (que solo tenía 8).
Aaron Bertrand
Tengo la edición web (limitada a menos de 4 sockets o 16 núcleos). En el antiguo servidor solo tenía 8 núcleos de todos modos.
prog_sr08
0

Tuve el mismo problema que el descrito en esta página: cambiar la configuración de energía de "equilibrado" a "alto rendimiento" marcó una diferencia dramática, más que duplicar los tiempos de respuesta. Ahora que estamos usando SSD, no creo que el consumo de energía sea el problema.

tom
fuente
-2

También he pasado por este problema durante al menos 2 semanas sin ninguna resolución sólida en lugar de confundir un problema con el otro.

Finalmente la resolución de la siguiente manera: -

  1. He restablecido la compatibilidad de 010 a 011

  2. Restablezca la compatibilidad de la base de datos maestra también. Por defecto, sql conservará la antigua configuración de compatibilidad. Que necesitamos cambiar manualmente.

Todo lo mejor

Pramod Kumar PC
fuente