Was bedeutet Fragmentierung in einem Haufen?
Der Fragmentierungswert in Heap, den Sie avg_fragmentation_in_percent
durch Abfragen von sys.dm_db_index_physical_stats
DMV aus der Spalte erhalten, gibt dies an
Logische Fragmentierung für Indizes oder Extent-Fragmentierung für Heaps in der Zuordnungseinheit IN_ROW_DATA.
Weiter sagt das gleiche BOL das
Dies ist der Prozentsatz der nicht in der Reihenfolge liegenden Ausmaße auf den Blattseiten eines Haufens. Ein Bereich außerhalb der Reihenfolge ist ein Bereich, bei dem der Bereich, der die aktuelle Seite für einen Heap enthält, physisch nicht der nächste Bereich nach dem Bereich ist, der die vorherige Seite enthält.
Sie sehen also, dass nicht der freie Speicherplatz auf den Heap zugewiesenen Seiten, sondern die unterschiedliche Reihenfolge der Seiten die Fragmentierung verursacht.
Dies kann durch einen kleinen Test nachgewiesen werden. Lassen Sie uns eine Heap-Tabelle erstellen, einige Datensätze einfügen und dann die Fragmentierung überprüfen.
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')
Die Heap-Tabelle wird also mit 50 Datensätzen erstellt. Nachfolgend sehen Sie, wie die Fragmentierung nach der Abfrage DMV sys.dm_db_index_physical stats aussieht
Sie können sehen, dass der avg_fragmentation_in_percent
Spaltenwert 33% beträgt. Nun wollen wir sehen, wie die Seiten angeordnet sind. Dies kann mithilfe einer undokumentierten Abfrage erfolgen %%lockres%%
. Die Abfrage wäre
SELECT %%lockres%%, * FROM dbo.HeapTest;
Und unten sehen Sie, wie die Ausgabe aussieht. Nur relevanten Teil davon anhängen. Die Abfrage ergab 50 Zeilen, da wir 50 Zeilen in unsere Tabelle dbo.HeapTest eingefügt haben.
Es heißt, die erste Seite hat eine ID, 197
die nächste Seite hat eine ID. Die 242
nachfolgenden Seiten haben eine fortlaufende ID, bis wir die Seiten-ID erreichen, 264
da wir danach die Seiten-ID erhalten 280
. Dieser Sprung in den Seiten-ID-Nummern verursacht also tatsächlich eine Fragmentierung.
Damit der Heap nicht neu erstellt und der Befehl erneut ausgeführt wird, um die Fragmentierung und die Anordnung der Seiten anzuzeigen. Wir bekommen Fragmentierung wie
Sie können sehen, Fragmentierung ist jetzt 14%
.
Lassen Sie uns die zugewiesenen Seitenzahlen sehen
Wir haben nur eine Sprungauflage. Allen Seiten wird die Seiten-ID seriell zugewiesen. Da nur eine Sprungfragmentierung erheblich abnahm.
Ich habe den Heap wieder aufgebaut und jetzt, als ich die Fragmentierung überprüft habe, war er vollständig verschwunden. Und die Zuweisung der Seiten-ID ist wie
Warum die Fragmentierung zunahm
In Bezug auf das, was zu einem Anstieg der Fragmentierung hätte führen können, können wir bestätigen, dass Seiten, die dem Heap zugewiesen wurden, nicht kontinuierlich waren, wie Sie oben gesehen haben, was zu einem Anstieg des Fragmentierungswerts führte, war ein Sprung in die den Seiten zugewiesenen PAGE-IDs.
Am Hinterkopf sollten Sie auch bedenken, dass das Wort Fragmentierung für HEAP keine Bedeutung hat. Wie würden Sie die Fragmentierung für eine Reihe nicht geordneter Seiten definieren?
Wirklich besorgt über Fragmentierung
Wenn Sie wirklich mit einem Szenario konfrontiert sind, in dem die Heap-Tabelle fragmentiert ist und Abfragen verlangsamt, ist es besser, einen Clustered-Index für die Tabelle zu erstellen, als ihn neu zu erstellen. Der Grund dafür ist, dass beim Neuerstellen des Heaps alle zugrunde liegenden Nicht-Clustered-Indizes ebenfalls neu erstellt werden, was dazu führt, dass der Wiederherstellungsprozess viel länger dauert, viele Ressourcen verbraucht und das Transaktionsprotokoll aufgebläht wird. Auf einem Produktionssystem würde man immer versuchen, dies zu vermeiden. Paulus hat dies in seiner Mythos-Sektion über Haufen behandelt .
PS: Bitte verwenden Sie keinen undokumentierten Befehl auf dem Produktionssystem. Dies war nur zur Demonstration.