Tenemos una gran base de datos, de aproximadamente 1 TB, que ejecuta SQL Server 2014 en un servidor potente. Todo funcionó bien durante unos años. Hace aproximadamente 2 semanas, realizamos un mantenimiento completo, que incluyó: Instalar todas las actualizaciones de software; reconstruir todos los índices y archivos DB compactos. Sin embargo, no esperábamos que en cierta etapa el uso de la CPU de la base de datos aumentara en más del 100% al 150% cuando la carga real era la misma.
Después de muchos problemas, lo hemos reducido a una consulta muy simple, pero no hemos podido encontrar una solución. La consulta es extremadamente simple:
select top 1 EventID from EventLog with (nolock) order by EventID
¡Siempre toma alrededor de 1.5 segundos! Sin embargo, una consulta similar con "desc" siempre toma alrededor de 0 ms:
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTable tiene alrededor de 500 millones de filas; EventID
es la columna de índice agrupada primaria (ordenada ASC
) con el tipo de datos de bigint (columna de identidad). Hay varios subprocesos que insertan datos en la tabla en la parte superior (EventIDs más grandes), y hay 1 subproceso que elimina datos desde la parte inferior (EventIDs más pequeños).
En SMSS, verificamos que las dos consultas siempre usan el mismo plan de ejecución:
Exploración de índice agrupado;
Los números de fila estimados y reales son ambos 1;
El número estimado y real de ejecuciones son ambos 1;
El costo estimado de E / S es de 8500 (parece ser alto)
Si se ejecuta consecutivamente, el costo de la consulta es el mismo 50% para ambos.
Actualicé las estadísticas del índice with fullscan
, el problema persistió; Reconstruí el índice nuevamente, y el problema pareció desaparecer durante medio día, pero regresó.
Encendí las estadísticas de IO con:
set statistics io on
luego ejecutó las dos consultas consecutivamente y encontré la siguiente información:
(Para la primera consulta, la lenta)
Tabla 'PTable'. Recuento de escaneo 1, lecturas lógicas 407670, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura lob 0.
(Para la segunda consulta, la rápida)
Tabla 'PTable'. Cuenta de escaneo 1, lecturas lógicas 4, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas lob de lectura anticipada 0.
Tenga en cuenta la gran diferencia en las lecturas lógicas. El índice se usa en ambos casos.
La fragmentación del índice podría explicar un poco, pero creo que el impacto es muy pequeño; y el problema nunca antes había sucedido. Otra prueba es si ejecuto una consulta como:
select * from EventLog with (nolock) where EventID=xxxx
Incluso si configuro xxxx a los EventID más pequeños de la tabla, la consulta siempre es muy rápida.
Verificamos y no hay problema de bloqueo / bloqueo.
Nota: acabo de intentar simplificar el problema anterior. El "PTable" es en realidad "EventLog"; El PID
es EventID
.
Obtengo el mismo resultado de prueba sin la NOLOCK
pista.
¿Alguien puede ayudar?
Planes de ejecución de consultas más detallados en XML de la siguiente manera:
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
No creo que sea importante proporcionar la declaración de crear tabla. Es una base de datos antigua y ha estado funcionando perfectamente bien durante mucho tiempo hasta el mantenimiento. Hemos investigado mucho nosotros mismos y lo hemos reducido a la información proporcionada en mi pregunta.
La tabla se creó normalmente con la EventID
columna como clave principal, que es una identity
columna de tipo bigint
. En este momento, supongo que el problema es con la fragmentación del índice. Justo después de la reconstrucción del índice, el problema pareció desaparecer durante medio día; pero ¿por qué volvió tan rápido ...?