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 Índices con fragmentación > 30% suelen requerir REBUILD; entre 5-30% REORGANIZE es suficiente.
- 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.
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?
La guía estándar de Microsoft es un archivo de tempdb por núcleo lógico hasta un máximo de 8. Si tu servidor tiene 16 cores y tempdb tiene 1 archivo, puedes estar generando contención de asignación de páginas (SGAM/GAM), que se manifiesta como waits PAGELATCH_EX en tempdb. Los archivos deben ser del mismo tamaño inicial y estar en un disco rápido dedicado (preferiblemente SSD o NVMe).
¿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. CXPACKET indica paralelismo, que no siempre es malo. El problema es cuando el paralelismo desequilibrado (CXPACKET muy alto con poco trabajo real) ralentiza consultas individuales. La recomendación de Microsoft es configurar MAXDOP a la mitad de los núcleos por socket, hasta 8, y ajustar el Cost Threshold for Parallelism a un valor mayor (25-50) para que solo las consultas costosas usen paralelismo.