Pourquoi mes index non cluster utilisent-ils plus d'espace lorsque je supprime des lignes?

22

J'ai une grande table avec 7,5 milliards de lignes et 5 index. Lorsque je supprime environ 10 millions de lignes, je remarque que les index non clusterisés semblent augmenter le nombre de pages sur lesquelles ils sont stockés.

J'ai écrit une requête contre dm_db_partition_statspour signaler la différence (après - avant) dans les pages:

deltas dm_db_partition_stats

L'index 1 est l'index clusterisé, l'index 2 est la clé primaire. Les autres sont non clusterisés et non uniques.

Pourquoi les pages augmentent-elles sur ces index non groupés?
Je m'attendais à ce que les chiffres restent au pire les mêmes.
Je constate que les compteurs de performances signalent une augmentation des sauts de page pendant la suppression.

Lors de la suppression, l'enregistrement fantôme doit-il passer à une autre page? Est-ce que cela a à voir avec les "uniques"?

Nous sommes en train de déployer RCSI, mais pour l'instant, RCSI est désactivé.

Il s'agit d'un nœud principal dans un groupe de disponibilité. Je sais que l'instantané est utilisé d'une manière ou d'une autre sur les secondaires. Je serais surpris si cela était pertinent. J'ai l'intention de creuser dans ce (en regardant la sortie de la page dbcc) pour en savoir plus. Espérons que quelqu'un a vu quelque chose de similaire.

Michael J Swart
la source
Juste une question - exécuter une RÉORGANISATION sur l'un des index qui a augmenté, que se passe-t-il? Combien de pages sont supprimées? Et si vous vous réorganisez avant de supprimer, que se passe-t-il? Je pense principalement que les mécanismes internes pourraient trouver plus facile dans certains cas d'allouer une nouvelle page entière et de fusionner, mais ne nettoie pas les pages vides. Je sais que REORGANIZE finit par perdre des quantités importantes de pages, même sur des index relativement non fragmentés mais plus volumineux.
Laughing Vergil
Bonne question @LaughingVergil Quand j'aurai la réponse, je reviendrai ici pour la rapporter. (Mais cela peut prendre un certain temps).
Michael J Swart
Dans notre cas, cette augmentation était un phénomène temporaire. Avec suffisamment de patience, le nettoyage des fantômes a finalement fait son travail et la taille des index a diminué.
Michael J Swart

Réponses:

28

Un scénario possible qui m'amuse beaucoup:

  • Les lignes ont été écrites à l'origine lorsque la base de données n'avait pas activé la lecture de l'instantané validé (RCSI), l'isolement de l'instantané (SI) ou les groupes de disponibilité (AG).
  • RCSI ou SI a été activé ou la base de données a été ajoutée à un groupe de disponibilité
  • Pendant les suppressions, un horodatage de 14 octets a été ajouté aux lignes supprimées pour prendre en charge les lectures RCSI / SI / AG

Étant donné que ce serveur est un serveur principal dans un AG, il est affecté tout comme les secondaires. Les informations de version sont ajoutées sur le primaire - les pages de données sont exactement les mêmes sur les primaires et les secondaires. Les secondaires exploitent le magasin de versions pour effectuer leurs lectures pendant que les lignes sont mises à jour par l'AG, mais les secondaires n'écrivent pas leurs propres versions de l'horodatage sur la page. Ils héritent juste les versions du travail du primaire.

Pour démontrer la croissance, j'ai pris l'exportation de la base de données Stack Overflow (qui n'a pas activé RCSI) et créé un tas d'index sur la table Posts. J'ai vérifié la taille des index avec sp_BlitzIndex @Mode = 2 (copié / collé dans une feuille de calcul et nettoyé un peu pour maximiser la densité des informations):

sp_BlitzIndex avant

J'ai ensuite supprimé environ la moitié des lignes:

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

De manière amusante, alors que les suppressions se produisaient, le fichier de données augmentait pour accueillir les horodatages aussi! Le rapport d'utilisation du disque SSMS montre les événements de croissance - voici juste le haut pour illustrer:

Événements de croissance

(Je dois aimer une démo où les suppressions font grandir la base de données.) Pendant la suppression, j'ai exécuté à nouveau sp_BlitzIndex. Notez que l'index cluster a moins de lignes, mais sa taille a déjà augmenté d'environ 1,5 Go. Les index non cluster sur AcceptedAnswerId ont considérablement augmenté - ce sont des index sur une petite valeur qui est généralement nulle, donc leur taille d'index a presque doublé!

sp_BlitzIndex lors de la suppression

Je n'ai pas à attendre la fin de la suppression pour le prouver, alors je vais arrêter la démo ici. Le point étant: lorsque vous effectuez de grandes suppressions sur une table qui a été implémentée avant l'activation de RCSI, SI ou AG, les index (y compris le cluster) peuvent en fait augmenter pour s'adapter à l'ajout de l'horodatage du magasin de versions.

Brent Ozar
la source
3
Telle est l'explication. Il s'avère que d'autres circonstances peuvent entraîner la disparition de 14 octets de version. Dans mes tests, il semble que la reconstruction d'un index hors ligne reconstruira les lignes sans les octets de version.
Michael J Swart