Podría suceder que una pequeña cantidad de datos alcance un cierto límite en SQL Server para forzar otro plan o algo así. Esto no es improbable. Pero el hecho de que su disco parece estar muy bajo deber me lleva a otra conclusión.
Hay 2 posibles razones básicas para su desaceleración.
- Actualizaste tu sistema y lo reiniciaste
- Cargas un montón de datos en él
Echemos un vistazo a la parte n. ° 1
Es posible que su configuración de SQL Server esté rota. Esto puede causar serios problemas con respecto a la velocidad de su servidor y el uso del disco.
Compruebe en primera instancia la configuración básica de su servidor. Esos ajustes básicos son max server memory
, affinity I/O mask
, affinity mask
y max degree of parallelism
. Es posible que deba habilitar las opciones avanzadas usando show advanced options
.
Aquí hay un script completo:
-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'
Compare el resultado con sus valores documentados en sus pasos de instalación. ¿Siguen siendo los mismos?
Puede tener muchas razones por las que su servidor se comporta de manera extraña. Normalmente apostaría a que tu max server memory
simplemente está equivocado. Esto hará que su servidor SQL intercambie permanentemente páginas de datos. No puede guardar todo en su memoria. Esto significa que necesita leer las páginas del disco, actualizarlo y volver a escribirlo instantáneamente. Si aparece otra actualización y usa la misma página para una actualización, no se puede leer desde la memoria. En cambio, el servidor necesita leerlo nuevamente desde el disco. Solo intercambiando ...
Otro problema puede ser una afinidad alta en disco o procesos. Si utilizó un servidor compartido (SQL Server + otros servicios) con un disco dedicado para SQL Server (que puede ser un caso raro, pero podría serlo), este podría ser su problema. Su servidor normalmente solía tener, por ejemplo, 3 cpus para procesos y uno para E / S. Los otros 12 cpus se utilizan para otros servicios. En este caso, su máscara de afinidad es incorrecta y utiliza, por ejemplo, una configuración automática. Esto significa que su servidor utiliza los 16 núcleos para procesos y E / S dinámicamente. Si tiene grandes procesos en ejecución, pueden poner una gran carga en el disco, lo que puede no manejar. Pero, de hecho, no creo que este sea tu caso. Sería más rápido (aunque sea un poco) si esto se aplicara, pero su caso es más lento.
Otro problema puede ser un grado demasiado alto de paralelismo. Lo que significa que tiene demasiados hilos inactivos en un parcial de una consulta. Esto también podría causar una gran desaceleración si el paralelismo no funciona como se esperaba. Pero esto no describirá su alta E / S en total.
Ahora echemos un vistazo a la parte n. ° 2 también
Cargas un montón de filas en tu sistema. Incluso si este es un trabajo regular, podría aumentar un límite en el que sus planes de consulta se intensifiquen. Incluso podría ocurrir que su inserción en combinación con SQL Server produzca este comportamiento.
Usted mencionó que ya intentó migrar sus índices a otro disco, lo que parece ser útil. Esto puede suceder solo por el hecho de que divide la carga en dos discos diferentes.
Puede ser que sus índices se hayan fracturado, que sus planes se hayan fracturado o que sus estadísticas estén desactualizadas.
1. verifiquemos la última actualización de estadísticas
Puede hacer esto manualmente a través de la interfaz para cada elemento estadístico. Lo cual sería un dolor. O puedes probar este código:
SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
Esto le dará una información completa sobre cada índice (y montón) y las estadísticas detrás de ellos. Incluso si ejecuta sp_updatestats
, no significa que las estadísticas se hayan actualizado. La parte en la que una actualización es bastante complicada, incluso si ejecuta sp_updatestats
o incluso si auto update statistics
está habilitada, las estadísticas no se actualizarán justo a tiempo. Aquí hay algunos puntos de borde, cuando se necesita / genera una actualización:
- Una tabla vacía obtiene una o más filas
- Una tabla con más de 500 filas actualiza 20% + 500 filas adicionales y luego se insertó una inserción
- Cuando se cambiaron 500 filas en una tabla que contiene menos de 500 filas
Esto significa que sus estadísticas pueden estar desactualizadas incluso si ejecuta la actualización.
Puedes echar un vistazo a la consulta anterior. Si encuentra algunas estadísticas bastante antiguas en algunas tablas, puede ejecutar una actualización estadística manual para esta tabla:
UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN
Después de eso, es posible que desee darle a su servidor una patada en el culo para tirar todos los planes antiguos.
DBCC FREEPROCCACHE
Si solo desea limpiar todos los cachés, puede ejecutar esto en su lugar:
DBCC FREESYSTEMCACHE ('ALL')
Esto limpiará todos los cachés, no solo el caché del plan. Normalmente advierto que use esto en un servidor de producción en la fase de producción. Pero como su servidor no funciona actualmente, no puede dañarlos demasiado. Puede ralentizarse durante algunos segundos, tal vez 1-2 minutos, ya que necesita reconstruir todos los cachés, pero después de eso debe correr con los planes correctos.
Otra razón puede ser índices totalmente fragmentados. Esto se puede verificar en todo el servidor utilizando esta declaración:
SELECT *
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)
Si la fragmentación es muy alta, es posible que deba reorganizarla (fragmentación <20%) o reconstruirla por completo (> 20%). Esto puede ejercer más presión sobre su disco y causar problemas. Por otro lado, si los índices son tan malos, probablemente ayudaría al final más de lo que perjudica.
Además de estas dos razones, todavía puede haber un tercer problema.
Es posible que su servidor esté configurado probablemente, no ha cambiado ningún código en este momento, solo ha agregado algunas filas. Todas las estadísticas se actualizan y todas las cachés se reconstruyen. Todos sus índices se reorganizan de la forma en que los necesita, pero aún así, nada funciona. Es posible que haya alcanzado el límite de memoria disponible en sus procesos. Quizás necesites más. Simplemente puede verificar si hay algún proceso que intente obtener más memoria de la que tiene.
Puede verificar esto usando este comando:
SELECT * FROM sys.dm_exec_query_memory_grants
Le proporcionará una lista de todas las sesiones que consumen memoria. Puede haber alguna consulta que todavía está esperando obtener memoria. Esas consultas se pueden filtrar fácilmente. Todas las sesiones donde granted_memory_kb IS NULL
. Estas son sesiones que solicitaron memoria pero no la obtienen. Otra cosa puede ser una memoria garantizada que puede ser demasiado baja. Puedes comparar las columnas requested_memory_kb
con granted_memory_kb
. La cantidad solicitada muestra la cantidad de memoria que el proceso necesita para ejecutarse de manera óptima, mientras que si se otorga, muestra la memoria habilitada para el proceso. Si un proceso necesita 2 GB para ejecutarse pero solo obtiene 2 MB ... puede obtenerlo usted mismo. ;-)
Otra forma es verificar RESSOURCE_SEMAPHORE
:
SELECT * FROM sys.dm_exec_query_resource_semaphore
Puedes echar un vistazo a la waiter_count
y la grantee_count
. Si el camarero está por encima de 0, tiene presión en su memoria, lo que puede causar un intercambio y puede causar la presión del disco que ve en el perfmon.