Síntomas comunes
- Consultas que antes tardaban segundos ahora toman minutos o generan timeout
- SSMS o el monitor de actividad muestran sesiones en espera con wait_type elevado
- SQL Server Agent jobs que no terminan en la ventana esperada
- El servidor muestra uso de CPU o I/O elevado y sostenido
- Reportes de bloqueos frecuentes reportados por la aplicación
- sys.dm_exec_requests muestra muchas solicitudes con status = 'suspended'
Riesgos para el negocio
- Timeouts en transacciones críticas de negocio: ventas, pagos, inventario
- Reportes e indicadores de gestión indisponibles cuando se necesitan
- Escalada a incidente si los bloqueos causan deadlocks en cascada
- SLA de integraciones con socios o clientes incumplido por demoras en APIs
Checklist técnico detallado
- 1. Top 10 queries por CPU total (desde última compilación)
- 2. Índices faltantes sugeridos por el motor El motor acumula sugerencias de índices observando los planes de ejecución. Impacto alto = mayor beneficio potencial.
- 3. Índices no utilizados (candidatos a eliminar) Los índices sin uso ralentizan las escrituras y consumen espacio. Verificar que llevan más de un reinicio sin uso.
- 4. Verificar configuración de memoria del servidor Si physical_memory_in_use_kb está cerca de max server memory, SQL Server puede estar presionado en memoria.
- 5. Estado y contención de tempdb tempdb con un solo archivo en servidores multi-core genera contención severa en páginas de sistema.
- 6. Fragmentación de índices en tablas grandes El porcentaje de fragmentación por sí solo no determina si conviene REORGANIZE o REBUILD. También se evalúan el tamaño del índice, la densidad de páginas, el patrón de acceso, el impacto en el log y el beneficio real para la carga.
- 7. Verificar estadísticas desactualizadas Estadísticas viejas hacen que el optimizador subestime o sobreestime filas y elija planes ineficientes.
- 8. I/O por archivo de base de datos Si un archivo de datos tiene latencia alta, el cuello de botella puede estar en el almacenamiento, no en el motor.
-- Top de esperas activas del servidor
SELECT TOP 10 wait_type, wait_time_ms, waiting_tasks_count
FROM sys.dm_os_wait_stats
WHERE wait_time_ms > 0
ORDER BY wait_time_ms DESC;
Cuándo escalar el incidente a un DBA especialista
- CXPACKET wait muy alto que no mejora ajustando MAXDOP — puede indicar un problema de paralelismo más profundo
- ASYNC_NETWORK_IO dominante — la aplicación consume datos muy lento y puede ser un problema de arquitectura
- Deadlocks frecuentes (más de 1 por hora) afectando transacciones de negocio
- Bloqueos en cadena que no se resuelven solos y requieren intervención manual repetida
- El servidor alcanza 100% de CPU o queda sin memoria disponible para SQL Server
Preguntas frecuentes
¿Qué significa PAGEIOLATCH_SH en los wait stats?
Es uno de los waits más comunes. Indica que una consulta está esperando cargar una página de datos desde disco al buffer pool (memoria caché de SQL Server). Si es la espera dominante, SQL Server no tiene suficiente memoria para mantener los datos más accedidos en caché, o hay un problema de latencia en el subsistema de almacenamiento. Revisar max server memory, verificar si el servidor compite con otras aplicaciones por RAM, y analizar el I/O con sys.dm_io_virtual_file_stats.
¿Cuántos archivos de tempdb debo tener?
No existe una fórmula fija como "siempre un archivo por núcleo". Un solo archivo en un servidor con muchos núcleos puede generar contención de asignación de páginas (SGAM/GAM), visible como waits PAGELATCH_EX en tempdb, pero el número correcto de archivos depende de la concurrencia real, el tipo de carga y la evidencia de contención observada. Se recomienda partir de una línea base, medir los waits antes y después, y ajustar de forma incremental. Los archivos deben tener el mismo tamaño inicial y estar en almacenamiento rápido dedicado.
¿Cómo sé si el problema está en el query o en la configuración del servidor?
Si un query específico domina sys.dm_exec_query_stats y su plan de ejecución tiene Table Scan en tablas grandes o Hash Join donde se esperaría Nested Loop, el problema está en el query o en la ausencia de índices. Si los wait stats muestran un tipo de espera dominante del servidor (PAGEIOLATCH_SH, CXPACKET excesivo, LCK_M_X), el problema es de configuración, recursos o contención estructural.
¿Debo configurar MAXDOP en 1 para eliminar CXPACKET?
No necesariamente, y tampoco existe una fórmula única para MAXDOP. CXPACKET indica paralelismo, que no siempre es malo; el problema aparece cuando el paralelismo desequilibrado ralentiza consultas individuales. Las recomendaciones de Microsoft varían según la topología NUMA y la cantidad de procesadores lógicos por nodo, y el valor debe validarse con la carga real, la concurrencia y el comportamiento de los waits de paralelismo antes de aplicarlo en producción. Suele evaluarse junto con el Cost Threshold for Parallelism, para que solo las consultas realmente costosas usen paralelismo.