Forwarded Records in SQL-Server-Heaps untersuchen
Verstehen Sie Zeilenverschiebungen im Heap, messen Sie gezielt Forwarded Records und entscheiden Sie zwischen Rebuild und einer passenden Tabellenstruktur.
Ein Heap kann eine passende Ablage für kurzlebige Daten sein und nach Monaten voller Updates anders reagieren. Wachsen variable Zeilen, reicht der ursprüngliche Seitenplatz möglicherweise nicht mehr. SQL Server kann die Zeile verschieben und am alten Ort einen Verweis hinterlassen.
Zeilenwachstum im Test nachstellen
Ein Heap besitzt keinen Clustered Index, darf aber Nonclustered-Indizes haben. Das Beispiel verwendet ausdrücklich einen nicht gruppierten Primärschlüssel. Andernfalls könnte die Schlüsseldefinition die Tabelle unbeabsichtigt zu einer gruppierten Tabelle machen. Verwenden Sie eine Übungsdatenbank mit freiem Objektnamen.
CREATE TABLE dbo.HeapForwardDemo
(
RowId int NOT NULL PRIMARY KEY NONCLUSTERED,
Payload varchar(1000) NOT NULL
);
;WITH N AS
(
SELECT TOP (10000)
CONVERT(int, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS n
FROM sys.all_objects AS a CROSS JOIN sys.all_objects AS b
)
INSERT dbo.HeapForwardDemo (RowId, Payload)
SELECT n, REPLICATE('a', 100) FROM N;
UPDATE dbo.HeapForwardDemo
SET Payload = REPLICATE('b', 900)
WHERE RowId % 2 = 0;
Die Nutzdaten sind anfangs kurz; anschließend wächst die Hälfte deutlich. Die Anzahl verschobener Zeilen hängt von Platzierung und freiem Raum ab. Erwarten Sie keinen festen Prozentsatz, sondern messen Sie.
SELECT
index_id, partition_number, alloc_unit_type_desc,
page_count, record_count,
forwarded_record_count,
avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats
(
DB_ID(), OBJECT_ID(N'dbo.HeapForwardDemo'), 0, NULL, 'DETAILED'
)
WHERE alloc_unit_type_desc = 'IN_ROW_DATA';
Die Abfrage untersucht gezielt einen Heap im Modus DETAILED. Physische Statistikabfragen können beträchtliche I/O-Arbeit verursachen. Nutzen Sie passende Datenbankrechte und entfernen Sie den Objektfilter nicht beiläufig auf einem großen Produktivsystem.
forwarded_record_count belegt Verschiebungen. page_count und Seitenauslastung beschreiben die weitere Struktur. Ein NULL-Wert bei weniger detaillierter Erfassung bedeutet nicht null verschobene Zeilen. Bewahren Sie Modus, Partition und Allocation Unit zusammen mit den Werten auf.
Struktur und Abfragearbeit verbinden
Nonclustered-Indizes eines Heaps verwenden Zeilenlokatoren, die zunächst zum ursprünglichen Ort und dann zur verschobenen Zeile führen können. Das erhöht möglicherweise die Navigation, erklärt aber allein noch keine Benutzerlatenz. Zugriffsweg, Cache und Lesehäufigkeit bestimmen die Wirkung.
Suchen Sie betroffene Abfragen und erfassen Sie logische Zugriffe, CPU, Dauer und tatsächliche Pläne für passende Parameter. Vergleichen Sie ähnliche Last. Werden Zeilen zugleich neunmal breiter, können zusätzliche Seiten und geringere Zeilenzahl pro Seite einen Teil der Mehrarbeit unabhängig von Verweisen erklären.
Ein abdeckender Nonclustered-Index kann bei einer bestimmten Abfrage den Zugriff auf den Heap vermeiden. Er kostet jedoch Speicher und Schreibpflege, und andere Abfragen lesen weiterhin Basiszeilen. Wählen Sie Indizes nach Zugriffsmustern statt als verdeckten Ersatz für eine Ursachenanalyse.
Unterscheiden Sie Weiterleitungen außerdem von logischer Fragmentierung eines B-Baums. Ein Wartungsskript, das nur avg_fragmentation_in_percent betrachtet, kann am relevanten Problem vorbeigehen. Heapstruktur braucht eine eigene Interpretation und Bezug zur Last.
Eine passende Maßnahme wählen
Ein Heap-Rebuild kann vorhandene Weiterleitungen beseitigen, verhindert aber keine neuen durch spätere Updates. Die Befehle betreffen ausschließlich das Übungsobjekt. Führen Sie nach dem Rebuild die Inspektion erneut aus, bevor Sie die Tabelle entfernen.
ALTER TABLE dbo.HeapForwardDemo REBUILD;
-- Run the inspection query again before removing the test table.
DROP TABLE dbo.HeapForwardDemo;
Planen Sie produktiv Dauer, Logkapazität, Platz, Sperren und Auswirkungen auf Nonclustered-Indizes. Nur einen Nonclustered-Index neu aufzubauen ordnet die Basiszeilen des Heaps nicht neu. Ein beliebiger Grenzwert für Forwarded Records begründet deshalb keinen großen Wartungslauf.
Ein geeigneter Clustered Index kann zu dauerhaften Tabellen mit häufigen Schlüsselzugriffen und Updates passen. Er verändert aber Zeilenlokatoren und bringt eigene Kosten für Seitenteilungen und Schlüsselbreite. Wählen Sie einen stabilen Schlüssel anhand der Last.
Bei Staging-Daten, die geladen, verarbeitet und verworfen werden, kann der Heap sinnvoll bleiben. Wartung lässt sich dann an den Batchlebenszyklus binden. Bei persistenten wachsenden Zeilen prüfen Sie, ob spätere Vergrößerungen fachlich notwendig sind oder vom aktuellen Schreibablauf verursacht werden.
Verbinden Sie die Nachmessung mit Abfrageverhalten und Wiederkehr. Kehren Verweise schnell zurück, ohne dass ein Rebuild Latenz verbessert, behandelt regelmäßiger Neuaufbau nur ein Symptom. Dokumentieren Sie auch Zeit seit dem letzten Ladevorgang und Updatevolumen. Damit stützt sich die Wartungsentscheidung auf den tatsächlichen Lebenszyklus der Tabelle.
Technische Referenzen: Microsoft Learn: Heaps · Microsoft Learn: Index physical statistics · Microsoft Learn: ALTER TABLE.