web-dev-qa-db-fra.com

Comment réduire la fragmentation HEAP dans SQL Server?

j'ai récemment découvert qu'une table de tas avait plus de 70% de fragmentation. J'ai donc décidé de faire un

ALTER TABLE dbo.myTable REBUILD

Assez drôle, après j'ai eu une fragmentation de 20%. Depuis, il n'y a plus eu d'écriture sur cette table. J'ai donc décidé de refaire la reconstruction.

Après la 2e fois, le chapeau de table est à 50% de fragmentation donc même plus! Je ne comprends vraiment pas comment cela peut se produire ...

10
tuxmania

Que signifie la fragmentation dans un tas

La valeur de fragmentation dans le tas que vous obtenez de la colonne avg_fragmentation_in_percent en interrogeant sys.dm_db_index_physical_stats DMV déclare que

Fragmentation logique pour les index ou fragmentation d'étendue pour les segments dans l'unité d'allocation IN_ROW_DATA.

De plus, le même BOL dit que

Il s'agit du pourcentage d'extensions dans le désordre dans les pages feuilles d'un segment. Une étendue en désordre est une étendue pour laquelle l'étendue qui contient la page en cours pour un segment de mémoire n'est pas physiquement l'étendue suivante après l'étendue qui contient la page précédente.

Ainsi, vous pouvez voir que ce n'est pas l'espace libre présent dans les pages allouées à Heap mais la séquence de pages variable qui crée la fragmentation.

Cela peut être démontré par un petit test. Créons une table de tas et insérons-y quelques enregistrements, puis vérifions la fragmentation.

create table dbo.HeapTest
(
Id INT not NULL Default (1),
Col1   char(5000) Not null Default ('Heaps Are Cool')
)

SET NOCOUNT ON

Insert into dbo.Heaptest default values
go 50

select index_type_desc,avg_fragmentation_in_percent,fragment_count,
avg_page_space_used_in_percent,record_count
from sys.dm_db_index_physical_stats(db_id(),object_id('dbo.HeapTest','U'),0,default,'detailed')

La table Heap est donc créée avec 50 enregistrements. Voici à quoi ressemble la fragmentation après la requête DMV sys.dm_db_index_physical stats

enter image description here

Tu peux voir avg_fragmentation_in_percent la valeur de la colonne est de 33%. Voyons maintenant comment les pages sont organisées. Cela peut être fait en utilisant requête non documentée %%lockres%%. La requête serait

SELECT  %%lockres%%, * FROM dbo.HeapTest;

Et voici à quoi ressemble la sortie. Joindre seulement une partie pertinente de celui-ci. La requête a produit 50 lignes depuis que nous avons inséré 50 lignes dans notre table dbo.HeapTest.

enter image description here

Il indique que la première page a un ID 197 la page suivante a l'ID 242 les pages suivantes ont un ID continu jusqu'à ce que nous atteignions l'ID de la page 264 car après cela, nous obtenons l'ID de la page 280. Donc, ce saut dans les numéros d'identification de page est ce qui cause la fragmentation.

Maintenant, de peur de reconstruire le tas et d'exécuter à nouveau la commande pour voir la fragmentation et la disposition des pages. Nous obtenons une fragmentation comme

enter image description here

Vous pouvez voir que la fragmentation est maintenant 14%.

Voyons les numéros de page attribués

enter image description here

Nous avons seulement un saut de repos toutes les pages sont attribuées en série ID de page. Depuis un seul saut, la fragmentation a considérablement diminué.

Je reconstruis à nouveau le tas et maintenant, lorsque j'ai vérifié la fragmentation, elle avait complètement disparu. Et l'allocation des ID de page est comme

enter image description here

Pourquoi la fragmentation a augmenté

Maintenant, en ce qui concerne ce qui aurait pu augmenter la fragmentation, nous pouvons corroborer le fait que lorsque les pages étaient allouées au tas, elles ne seraient pas continues, comme vous l'avez vu ci-dessus, ce qui a provoqué l'augmentation de la valeur de la fragmentation a été l'augmentation des ID de PAGE alloués aux pages.

À l'arrière de la tête, vous devez également garder à l'esprit que la fragmentation de Word pour HEAP n'a aucune signification, comment définiriez-vous la fragmentation pour un tas de pages non ordonnées.

Vraiment inquiet de la fragmentation

Si vous êtes vraiment confronté à un scénario où la table de segment de mémoire est fragmentée et ralentit les requêtes, il serait préférable de créer un index clusterisé sur la table plutôt que de le reconstruire. La raison en est que lorsque vous reconstruisez le tas, tous les index non cluster sous-jacents sont également reconstruits, ce qui prend beaucoup plus de temps pour le processus de reconstruction, en utilisant beaucoup de ressources et un journal des transactions gonflé. Sur un système de production, on essaierait toujours d'éviter cela. Paul a couvert cela dans son Myth Section about heap .

PS: Veuillez ne pas utiliser de commande non documentée sur le système de production. C'était juste pour la démonstration.

17
Shanky