Perché i miei indici non cluster utilizzano più spazio quando elimino le righe?


22

Ho una grande tabella con 7,5 miliardi di righe e 5 indici. Quando cancello circa 10 milioni di righe, noto che gli indici non cluster sembrano aumentare il numero di pagine in cui sono memorizzati.

Ho scritto una domanda contro dm_db_partition_statsper segnalare la differenza (dopo - prima) nelle pagine:

delta dm_db_partition_stats

L'indice 1 è l'indice cluster, l'indice 2 è la chiave primaria. Gli altri sono non cluster e non unici.

Perché le pagine aumentano su quegli indici non cluster?
Mi aspettavo che i numeri nel peggiore dei casi fossero gli stessi.
Vedo che i contatori delle prestazioni segnalano un aumento delle divisioni di pagina durante l'eliminazione.

Quando si elimina, il record fantasma deve spostarsi su un'altra pagina? Questo ha a che fare con gli "unificatori"?

Siamo nel mezzo del lancio di RCSI, ma in questo momento RCSI è spento.

È un nodo primario in un gruppo di disponibilità. So che l'istantanea viene utilizzata in qualche modo sui secondari. Sarei sorpreso se fosse rilevante. Ho intenzione di scavare in questo (guardando l'output della pagina dbcc) per saperne di più. Spero che qualcuno abbia visto qualcosa di simile.


Solo una domanda: eseguire un RIORGANIZZAZIONE su uno degli indici che sono cresciuti, cosa succede? Quante pagine vengono rimosse? E se riorganizzi prima di eliminare, cosa succede? Per lo più sto pensando che i meccanismi interni potrebbero trovare più facile in alcuni casi allocare un'intera nuova pagina e unire, ma non ripulisce le pagine vuote. So che REORGANIZE finisce per far cadere quantità significative di pagine, anche su indici relativamente non frammentati ma più grandi.
Ridere Vergil il

Bella domanda @LaughingVergil Quando avrò la risposta, tornerò qui per segnalarla. (Ma potrebbe richiedere del tempo).
Michael J Swart,

Nel nostro caso, questo aumento è stato un fenomeno temporaneo. Con sufficiente pazienza, il lavoro di pulizia dei fantasmi alla fine ha fatto il suo lavoro e le dimensioni degli indici sono diminuite.
Michael J Swart,

Risposte:


28

Uno scenario possibile che mi diverte moltissimo:

  • Le righe erano originariamente scritte quando nel database non erano abilitati Read Committed Snapshot (RCSI), Snapshot Isolation (SI) o gruppi di disponibilità (AG)
  • RCSI o SI è stato abilitato o il database è stato aggiunto in un gruppo di disponibilità
  • Durante le eliminazioni, è stato aggiunto un timestamp di 14 byte alle righe eliminate per supportare le letture RCSI / SI / AG

Poiché questo server è un elemento primario in un'AG, è interessato proprio come lo sono i secondari. Le informazioni sulla versione vengono aggiunte al primario: le pagine dei dati sono identiche sia per le primarie che per le secondarie. I secondari sfruttano l'archivio versione per fare le loro letture mentre le righe vengono aggiornate dall'AG, ma i secondari non scrivono le proprie versioni del timestamp sulla pagina. Hanno ereditato le versioni dal lavoro del primario.

Per dimostrare la crescita, ho preso l'esportazione del database Stack Overflow (che non ha RCSI abilitato) e ho creato un gruppo di indici sulla tabella Posts. Ho controllato le dimensioni dell'indice con sp_BlitzIndex @Mode = 2 (copiato / incollato in un foglio di calcolo e ripulito un po 'per massimizzare la densità di informazioni):

sp_BlitzIndex prima

Ho quindi eliminato circa la metà delle righe:

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

In modo divertente, mentre stavano avvenendo le cancellazioni, il file di dati stava crescendo per adattarsi anche ai timestamp! Il rapporto sull'utilizzo del disco SSMS mostra gli eventi di crescita: ecco solo i primi per illustrare:

Eventi di crescita

(Devo amare una demo in cui le eliminazioni fanno crescere il database.) Mentre l'eliminazione era in esecuzione, ho eseguito di nuovo sp_BlitzIndex. Si noti che l'indice cluster ha meno righe, ma la sua dimensione è già cresciuta di circa 1,5 GB. Gli indici non cluster su AcceptedAnswerId sono cresciuti notevolmente: sono indici su un valore piccolo che è per lo più nullo, quindi le loro dimensioni degli indici sono quasi raddoppiate!

sp_BlitzIndex durante la cancellazione

Non devo aspettare che la cancellazione finisca per dimostrarlo, quindi interromperò la demo lì. Punto fondamentale: quando si eseguono grandi eliminazioni su una tabella implementata prima dell'abilitazione di RCSI, SI o AG, gli indici (incluso il cluster) possono effettivamente crescere per adattarsi all'aggiunta del timestamp dell'archivio versione.


3
Questa è la spiegazione Si scopre che ci sono altre circostanze che possono portare alla perdita di 14 byte di versione. Nel mio test sembra che ricostruire un indice offline ricostruirà le righe senza i byte di versione.
Michael J Swart,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.