RAM aumentada, peor rendimiento

9

Preparar:

  • Windows Server 2008 R2
  • SQL Server 2008 R2 SP1
  • 240 GB de RAM
  • TempDB son archivos de datos de 8x16 GB sin crecimiento automático (128 GB en total)
  • Servidor físico / independiente

Este servidor se utiliza para el procesamiento de ETL. Acabamos de instalar más RAM en este servidor para un total de 240 GB de RAM. Los servicios de SQL Server son las únicas cosas reales en ejecución.

La memoria se muestra bien en el BIOS, OpenManage y Windows.

Si configuro SQL Server para usar una memoria mínima / máxima de 70 / 100GB, no tenemos problemas. Sin embargo, una vez que aumento eso a 120 / 150GB, obtengo el siguiente error cuando ejecuto uno de nuestros procesos ETL:

No se pudo asignar espacio para el objeto '<objeto del sistema temporal: 422234507706368>' en la base de datos 'tempdb' porque el grupo de archivos 'PRIMARIO' está lleno. Cree espacio en disco eliminando archivos innecesarios, colocando objetos en el grupo de archivos, agregando archivos adicionales al grupo de archivos o configurando el crecimiento automático para los archivos existentes en el grupo de archivos. (Mensaje 1105, Estado 2, Procedimiento desconocido, Línea 1)

Nunca nos hemos encontrado con este problema antes de cambiar la configuración de la memoria. Después de reconfigurar nuevamente a los 70 / 100GB originales, no recibimos este error.

Cosas que he probado:

  1. Establezca los archivos de datos TempDB para crecer automáticamente. Esto simplemente hace que los archivos crezcan automáticamente hasta que se alcanza la capacidad del disco y luego falla.
  2. Agregue más archivos de datos TempDB. El mismo error que se muestra.
  3. Aumente el tamaño de TempDB a 8x32GB (256GB en total)

No sé qué podría estar causando este problema.

Derek Kromm
fuente
2
¿Su memoria está equilibrada en los nodos NUMA? ¿Qué hay de sus procesadores? ¿El registro de SQL Server muestra cuántas CPU están en uso durante el inicio?
Aaron Bertrand
1
¿Qué estás usando para los procesos ETL? SSIS o alguna herramienta similar? Si es una herramienta fuera de SQL Server, ¿la está ejecutando en el mismo servidor que su instancia de SQL Server?
Mike Fal
1
Ese es un buen punto @ Mike, si el proceso ETL no puede obtener suficiente memoria para hacer su trabajo, porque SQL Server está usando demasiado, entonces podría tener que llevar el trabajo a tempdb.
Aaron Bertrand
1
Aquí hay un buen comienzo para monitorear el uso de tempdb: msdn.microsoft.com/en-us/library/ms176029(v=SQL.105).aspx . Esto debería darle una idea de lo que está sucediendo.
Thomas Stringer
2
¿Ha hecho algún análisis de lo que realmente se está ejecutando cuando TempDB se está expandiendo? ¿Un simple sp_who2 / sp_whoisactive? Me parece que tiene algunas transacciones de larga duración que podrían gestionarse mejor, pero son difíciles de distinguir. Personalmente, no llegaría a adjuntarme al cambio de memoria, pero primero mire el código y vea si eso se está ejecutando correctamente.
Mike Fal

Respuestas:

3

Gracias a todos por vuestra ayuda.

Después de analizar algunos planes de ejecución, resulta que hay una UNIÓN que se procesa de manera diferente en función de la cantidad de RAM disponible. Con menos RAM lo evalúa con un Hash; con más RAM, usa una serie de Merge Joins.

Básicamente, todo se redujo a T-SQL mal escrito, que actualmente estoy refactorizando.

Derek Kromm
fuente
44
Eso es bastante contrario a la intuición porque una combinación hash requiere una concesión de memoria, mientras que la fusión no. ¿Existe una operación de clasificación adicional para admitir la combinación de combinación?
Martin Smith
1

Esta no es una respuesta a la pregunta, solo un código que no quería publicar en un comentario. Para ver el equilibrio de sus planificadores y memoria en los nodos NUMA (y también para ver si alguno de los nodos no está visible en línea):

SELECT 
  parent_node_id, 
  [status],
  AVG(current_tasks_count) AS avg_tasks_count, 
  AVG(load_factor) AS avg_load_factor,
  scheduler_count = COUNT(*)
FROM sys.dm_os_schedulers
GROUP BY parent_node_id, [status];

SELECT 
  memory_node_id, 
  name, 
  SUM(single_pages_kb + multi_pages_kb) AS memory_kb
FROM sys.dm_os_memory_clerks
GROUP BY memory_node_id, name;

(En SQL Server 2012, lo último SUMdebería ser SUM(pages_kb)porque ya no hay asignadores separados de una o varias páginas).

Aaron Bertrand
fuente