Wie kann dies geschehen, wenn wir einen Clustered-Index für eine Tabelle mit etwa 15 GB Daten neu erstellt und die Datengröße auf 5 GB verkleinert haben? Welche Art von "Daten" wird entfernt?
Datengröße Ich meine die "Daten" -Spalte von DBCC sp_spaceused
Vor dem erneuten Erstellen eines Clustered-Index:
name rows reserved data index_size unused LEDGERJOURNALTRANS 43583730 39169656 KB 15857960 KB 22916496 KB 395200 KB
Nach der Neuerstellung im Clustered-Index:
name rows reserved data index_size unused LEDGERJOURNALTRANS 43583730 29076736 KB 5867048 KB 22880144 KB 329544 KB
TSQL für den Wiederaufbau:
USE [DAX5TEST]
GO
ALTER INDEX [I_212RECID] ON [dbo].[LEDGERJOURNALTRANS] REBUILD PARTITION = ALL WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, ONLINE = ON, SORT_IN_TEMPDB = OFF, DATA_COMPRESSION = PAGE, FILLFACTOR = 85 )
GO
sql-server
clustered-index
Daniel Björk
quelle
quelle
EXEC sp_spaceused
.ALTER INDEX
Anweisung scheint vom Code generiert worden zu sein (da sie eine Reihe von Optionen in ihrer Standardeinstellung enthält), daher vermute ich, dass sie aus den vorhandenen Optionen des Index erstellt wurde. Aber Sie haben Recht: Wenn die Komprimierung für den Clustered-Index vor dieser Ausführung nicht aktiviert war, würde dies definitiv den größten Teil der Reduzierung des Daten-Footprints erklären. (Antworten:
Wenn eine Tabelle einen gruppierten Index hat, der Index ist die Datentabelle (sonst haben Sie eine Art Tabelle Heap). Eine Neuerstellung des Clustered-Index (tatsächlich ein Index, aber der Speicherplatz wird nicht als "Daten" für einen Nicht-Clustered-Index gezählt) führt dazu, dass teilweise verwendete Seiten zu einer vollständigeren Form zusammengeführt werden.
Wenn Sie Daten in Index (in Gruppen oder auf andere Weise) in Indexreihenfolge einfügen, werden nach Bedarf Blattseiten erstellt, und Sie haben immer nur eine Teilseite: die am Ende. Wenn Sie Daten außerhalb der Indexreihenfolge eingeben, muss eine Seite aufgeteilt werden, damit die Daten an die richtige Stelle passen: Sie erhalten zwei Seiten, die ungefähr halb voll sind, und die neue Zeile wird in eine davon eingefügt. Im Laufe der Zeit kann dies viel passieren und viel zusätzlichen Platz beanspruchen, obwohl zukünftige Einfügungen in gewissem Maße einige der Lücken füllen werden. Nicht-Blattseiten haben ebenfalls einen ähnlichen Effekt, aber die tatsächlichen Datenseiten sind weitaus bedeutender als sie.
Auch Löschvorgänge können zu Teilseiten führen. Wenn Sie alle Zeilen auf einer Seite entfernen, wird sie als "nicht verwendet" gezählt. Wenn jedoch eine oder mehrere Datenzeilen übrig sind, wird sie weiterhin als verwendet gezählt. Selbst wenn eine Seite nur eine Zeile mit 10 Byte enthält, zählt diese Seite als 8192 Byte in der Anzahl des verwendeten Speicherplatzes. Wiederum könnten zukünftige Beilagen einen Teil der Lücke füllen.
Bei Zeilen mit variabler Länge können Aktualisierungen auch den gleichen Effekt haben: Wenn eine Zeile kleiner wird, bleibt möglicherweise Platz auf ihrer Seite, der später nicht mehr einfach wiederverwendet werden kann. Wenn eine Zeile auf einer fast vollständigen Seite länger wird, kann dies zu einer Seitenteilung führen .
SQL Server verbringt keine Zeit damit, zu versuchen, die Daten zu normalisieren, indem die Verwendung der Seiten neu angeordnet wird, bis dies explizit angegeben wird, z. B. Ihre Reihenfolge für die Indexwiederherstellung, da solche Speicherbereinigungsübungen ein Leistungsalptraum sein können.
Ich vermute, dass dies das ist, was Sie sehen, obwohl ich sagen würde, dass es ein besonders schlimmer Fall ist, wenn genügend Speicherplatz für das 2,7-fache der Menge zugewiesen wird, die die Daten unbedingt benötigen. Dies kann bedeuten, dass Sie etwas Zufälliges als einen der signifikanten Schlüssel im Index haben (möglicherweise eine UUID-Spalte), was bedeutet, dass neue Zeilen wahrscheinlich nie in Indexreihenfolge hinzugefügt werden und / oder dass in letzter Zeit eine signifikante Anzahl von Löschvorgängen stattgefunden hat.
Beispiel für Seitenaufteilung
Einfügen in Indexreihenfolge mit Zeilen fester Länge, von denen vier in eine Seite passen:
Nun zum Hinzufügen von Zeilen außerhalb der Indexreihenfolge (aus diesem Grund habe ich nur die oben genannten geraden Zahlen verwendet): Das Hinzufügen
11
würde bedeuten, dass entweder die zweite Seite erweitert wird (nicht möglich, da sie eine feste Größe haben) und alles über 11 nach oben verschoben wird (viel zu teuer) einen großen Index) oder teilen Sie die Seite wie folgt auf:Von hier aus führt das Hinzufügen
13
und17
nicht zu einer Aufteilung, da derzeit Platz auf den entsprechenden Seiten vorhanden ist:aber das Hinzufügen von 03 wird:
Wie Sie sehen können, sind nach diesen Einfügevorgängen derzeit 5 Datenseiten zugewiesen, die insgesamt 20 Zeilen aufnehmen können, aber wir haben dort nur 14 Zeilen ("Verschwendung" von 30% des Speicherplatzes).
Eine Neuerstellung mit Standardoptionen (siehe unten zum "Füllfaktor") würde Folgendes ergeben:
Speichern einer Seite in diesem einfachen Beispiel. Es ist leicht zu erkennen, wie Löschvorgänge einen ähnlichen Effekt haben können wie Einfügungen außerhalb der Indexreihenfolge.
Minderung
Wenn Sie erwarten, dass die Daten in Bezug auf die Indexreihenfolge in einer ziemlich zufälligen Reihenfolge vorliegen, können Sie die
FILLFACTOR
Option beim Erstellen oder Neuerstellen eines Index verwenden, um SQL Server anzuweisen, künstlich Lücken zu lassen, die später ausgefüllt werden sollen anfangs mehr platz nehmen. Natürlich kann es falsch sein, diesen Wert falsch zu machen, anstatt die Situation zu verbessern. Gehen Sie also vorsichtig vor.Das Aufteilen von Seiten, insbesondere im Clustered-Index, kann Auswirkungen auf die Leistung von Einfügungen / Aktualisierungen haben. Daher
FILLFACTOR
wird es manchmal aus diesem Grund optimiert, anstatt das Problem der Speicherplatznutzung in Datenbanken zu verursachen, in denen viel Schreibaktivität auftritt (bei den meisten Apps jedoch, bei denen Lesevorgänge Schreibvorgänge überwiegen) Um mehrere Größenordnungen ist es im Allgemeinen besser, den Füllfaktor bei 100% zu belassen, außer in bestimmten Fällen, in denen Sie Indizes über Spalten mit effektiv zufälligem Inhalt haben.Ich gehe davon aus, dass andere namhafte DBs eine ähnliche Option haben, wenn Sie diese Kontrolle auch in ihnen benötigen.
Aktualisieren
In Bezug auf die
ALTER INDEX
Anweisung, die der Frage hinzugefügt wurde, nachdem ich mit der Eingabe der obigen Informationen begonnen habe: Ich gehe davon aus, dass die Optionen dieselben sind wie bei der ersten Erstellung (oder der letzten Neuerstellung) des Index, aber wenn nicht, kann die Komprimierungsoption sehr wichtig sein, wenn sie hinzugefügt wird Zeit um. Auch in dieser Anweisung ist der Füllfaktor auf 85% und nicht auf 100% festgelegt, sodass jede Blattseite unmittelbar nach der Neuerstellung zu ~ 15% leer ist.quelle
Wenn Sie einen Index neu erstellen, werden buchstäblich alle Daten auf neuen Seiten platziert. Was ich vermute, ist, dass Sie vor der Neuerstellung viele Daten entfernt haben, z. B. eine Spalte entfernt, eine Spalte mit variabler Breite auf weniger Daten aktualisiert, eine Spaltengröße mit fester Breite geändert oder viele Zeilen gelöscht haben. Bei beiden Vorgängen kann auf den Seiten viel Platz frei bleiben, der erst nach der Neuerstellung zurückgefordert wird. In der Spalte "Daten" werden
sp_spaceused
nicht die tatsächlichen Daten gemessen, sondern die Anzahl der 8 KB-Seiten, auf denen die Daten gespeichert sind. Diese Seiten sind jetzt aufgrund der Neuerstellung voller, sodass dieselbe Datenmenge auf eine kleinere Anzahl von Seiten passt.quelle
Die
sp_spaceused
gespeicherte Prozedur untersucht nicht die Gesamtgröße der Zeilen in der Datenbank. Es gibt die Größe des zugewiesenen Speicherplatzes für diese Daten in der kumulierten Größe der für die Daten zugewiesenen Speicherbereiche an.Wenn ein erheblicher freier Speicherplatz verfügbar ist, z. B. aus vielen gelöschten Zeilen, würde eine Neuerstellung des Clustered-Index den Speicherplatz in Seiten und Bereichen komprimieren, um aus Leistungsgründen effizienter (dh kleiner) zu sein.
Es sollten also keine Daten verworfen worden sein, aber der Wiederherstellungsprozess machte den freien Speicherplatz, der in die Datenseiten eingebettet war, wieder verfügbar.
quelle