¿Por qué mis índices no agrupados usan más espacio cuando elimino filas?


22

Tengo una tabla grande con 7.5 mil millones de filas y 5 índices. Cuando elimino aproximadamente 10 millones de filas, noto que los índices no agrupados parecen aumentar el número de páginas en las que están almacenados.

Escribí una consulta en contra dm_db_partition_statspara informar la diferencia (después - antes) en las páginas:

deltas dm_db_partition_stats

El índice 1 es el índice agrupado, el índice 2 es la clave principal. Los otros no están agrupados ni son únicos.

¿Por qué aumentan las páginas en esos índices no agrupados?
En el peor de los casos, esperaba que los números permanecieran igual.
Veo que los contadores de rendimiento informan un aumento en las divisiones de página durante la eliminación.

Al eliminar, ¿el registro fantasma tiene que moverse a otra página? ¿Tiene esto que ver con los "unificadores"?

Estamos en medio de la implementación de RCSI, pero en este momento, RCSI está desactivado.

Es un nodo primario en un grupo de disponibilidad. Sé que la instantánea se usa de alguna manera en las secundarias. Me sorprendería si eso fuera relevante. Planeo profundizar en esto (buscando la salida de la página dbcc) para obtener más información. Espero que alguien haya visto algo similar.


Solo una pregunta: ejecutar un REORGANIZAR en uno de los índices que crecieron, ¿qué sucede? ¿Cuántas páginas se eliminan? Y si se reorganiza antes de eliminar, ¿qué sucede? Principalmente estoy pensando que los mecanismos internos podrían encontrar más fácil en algunos casos asignar una página nueva completa y fusionarla, pero no limpia las páginas vacías. Sé que REORGANIZAR termina dejando caer cantidades significativas de páginas, incluso en índices relativamente no fragmentados pero más grandes.
Riendo Vergil

Buena pregunta @LaughingVergil Cuando tenga la respuesta, volveré aquí para informarlo. (Pero puede llevar un tiempo).
Michael J Swart

En nuestro caso, este aumento fue un fenómeno temporal. Con suficiente paciencia, la limpieza fantasma eventualmente hizo su trabajo y los tamaños de los índices disminuyeron.
Michael J Swart

Respuestas:


28

Un posible escenario que me divierte mucho:

  • Las filas se escribieron originalmente cuando la base de datos no tenía Instantánea confirmada de lectura (RCSI), Aislamiento de instantánea (SI) o Grupos de disponibilidad (AG) habilitados
  • Se habilitó RCSI o SI, o la base de datos se agregó a un Grupo de disponibilidad
  • Durante las eliminaciones, se agregó una marca de tiempo de 14 bytes a las filas eliminadas para admitir lecturas RCSI / SI / AG

Dado que este servidor es primario en un AG, se ve afectado al igual que los secundarios. La información de la versión se agrega en la primaria: las páginas de datos son exactamente las mismas en las primarias y secundarias. Los secundarios aprovechan el almacén de versiones para hacer sus lecturas mientras el AG actualiza las filas, pero los secundarios no escriben sus propias versiones de la marca de tiempo en la página. Simplemente heredan las versiones del trabajo de la primaria.

Para demostrar el crecimiento, tomé la exportación de la base de datos Stack Overflow (que no tiene RCSI habilitado) y creé un montón de índices en la tabla Posts. Verifiqué los tamaños de índice con sp_BlitzIndex @Mode = 2 (copiar / pegar en una hoja de cálculo, y limpié un poco para maximizar la densidad de información):

sp_BlitzIndex antes

Luego eliminé aproximadamente la mitad de las filas:

BEGIN TRAN;
DELETE dbo.Posts WHERE Id % 2 = 0;
GO

¡Divertidamente, mientras ocurrían las eliminaciones, el archivo de datos crecía para acomodar las marcas de tiempo también! El Informe de uso de disco de SSMS muestra los eventos de crecimiento: aquí está solo la parte superior para ilustrar:

Eventos de crecimiento

(Me encantaría una demostración donde las eliminaciones hacen crecer la base de datos). Mientras se ejecutaba la eliminación, ejecuté sp_BlitzIndex nuevamente. Tenga en cuenta que el índice agrupado tiene menos filas, pero su tamaño ya ha aumentado en aproximadamente 1,5 GB. Los índices no agrupados en AcceptedAnswerId han crecido drásticamente: son índices en un valor pequeño que en su mayoría es nulo, ¡por lo que sus tamaños de índice casi se han duplicado!

sp_BlitzIndex durante la eliminación

No tengo que esperar a que termine la eliminación para probarlo, así que detendré la demostración allí. El punto es: cuando realiza grandes eliminaciones en una tabla que se implementó antes de que se habilitaran RCSI, SI o AG, los índices (incluido el agrupado) en realidad pueden crecer para acomodar la adición de la marca de tiempo del almacén de versiones.


3
Esta es la explicación. Resulta que hay otras circunstancias que pueden conducir a la falta de 14 bytes de versión. En mis pruebas, parece que reconstruir un índice fuera de línea reconstruirá las filas sin los bytes de la versión.
Michael J Swart
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.