Komprimierung auf einem Haufen

14

Das Folgende ist ein Absatz aus Microsoft Docs :

Neue Seiten, die im Rahmen von DML-Operationen in einem Heap zugewiesen wurden, verwenden die PAGE-Komprimierung erst, wenn der Heap neu erstellt wird. Erstellen Sie den Heap neu, indem Sie die Komprimierung entfernen und erneut anwenden oder indem Sie einen Clustered-Index erstellen und entfernen.

Ich kann nicht herausfinden, warum dies der Fall ist. Wenn ich einen Heap mit einer bestimmten Komprimierungseinstellung habe, warum wird er nicht auf eine Seite angewendet, die zur Tabelle gehört?

Vielen Dank

John Smith
quelle

Antworten:

12

Obwohl ich die spezifischen internen Mechanismen, die für die Unterschiede verantwortlich sind, nicht kenne, kann ich sagen, dass Heaps (intern) etwas anders verwaltet werden als Clustered-Indizes (und möglicherweise auch Nonclustered-Indizes):

  • Das Löschen von Zeilen aus einem Heap, sodass eine oder mehrere Datenseiten leer sind (keine zugewiesenen Zeilen), gibt diesen Speicherplatz nicht unbedingt frei. Sie müssen wahrscheinlich entweder einen Clustered Index für die Tabelle erstellen und dann löschen oder ALTER TABLE [TableName] REBUILD;(ab SQL Server 2014?) Aufrufen . Weitere Informationen und Optionen finden Sie auf der Microsoft Docs-Seite zum Löschen .

  • Durch das Einfügen einzelner Zeilen (dh nicht satzbasierter Operationen) werden beim erneuten Erstellen des Heaps so viele Zeilen gepackt, wie auf die Datenseite passen.INSERT ) in einen Heap werden die Datenseiten nicht so vollständig gefüllt wie bei Clustered-Indizes. Clustered-Indizes passen auf Zeilen, solange Platz für die Zeile (Daten und Zeilen-Overhead) plus dem 2-Byte-Overhead des Slot-Arrays vorhanden ist. Datenseiten in Heaps verwenden jedoch nicht die Anzahl der auf der Seite verbleibenden Bytes, sondern verwenden stattdessen einen sehr verallgemeinerten Indikator dafür, wie voll die Seite ist, und es werden nicht so viele Ebenen gemeldet. Die Levels sind ungefähr so: 0%, 20%, 50%, 80% und 100% voll. Und es wird auf 100% umgeschaltet, solange noch Platz für eine andere Zeile vorhanden ist (und wenn tatsächlich dieselbe Anzahl von Zeilen in einer satzbasierten Operation eingefügt worden wäre, hätte es die Seite so weit wie möglich gefüllt). Natürlich genauso wie bei derDELETE

Berücksichtigen Sie nun die folgenden Informationen aus dem Abschnitt "Wenn Seitenkomprimierung auftritt" auf der Microsoft Docs-Seite für die Implementierung der Seitenkomprimierung :

... Wenn der ersten Datenseite Daten hinzugefügt werden, werden die Daten zeilenkomprimiert. ... Wenn die Seite voll ist, leitet die nächste hinzuzufügende Zeile die Seitenkomprimierung ein. Die gesamte Seite wird überprüft. ...

Daher scheint es völlig im Einklang mit diesem anderen Heap-Verhalten zu stehen, dass ein ALTER TABLE REBUILD, CREATE / DROP eines Clustered Index oder eine Änderung der Einstellung für die Datenkomprimierung (die alle den Heap neu erstellen) erforderlich sind, bevor die Datenseiten geschrieben werden optimal. Wenn Heaps "ganze Seiten" nicht vollständig kennen (bis der Heap wiederhergestellt ist) und nicht wissen, wann die Seite definitiv voll ist, wissen sie nicht, wann der Seitenkomprimierungsvorgang einzuleiten ist (wenn es sich um Aktualisierungen und einzelne Seiten handelt) -Reiheneinsätze).

Eine weitere technische Besonderheit, die einige Heaps zusätzlich daran hindert, die Seitenkomprimierung automatisch anzuwenden (auch wenn dies sonst möglich wäre), besteht darin, dass für das Anwenden der Komprimierung alle Nonclustered-Indizes für diesen Heap (sofern vorhanden) neu erstellt werden müssen. Wie die verlinkte Seite für "Datenkomprimierung" auch besagt:

Wenn Sie die Komprimierungseinstellung eines Heaps ändern, müssen alle nicht gruppierten Indizes in der Tabelle neu erstellt werden, damit sie Zeiger auf die neuen Zeilenpositionen im Heap enthalten.

Die "Zeiger", auf die Bezug genommen wird, sind die Zeilen-IDs (RIDs), die eine Kombination aus: FileID, PageID und Slot / Position auf der Seite sind. Diese RIDs werden in Nonclustered-Indizes kopiert. Da es sich um einen genauen physischen Standort handelt, sind sie manchmal schneller als das Durchlaufen eines B-Baums mit den Schlüsseln für den gruppierten Index. Ein Nachteil eines physischen Standorts ist jedoch, dass er sich ändern kann, und genau darum geht es hier. Clustered-Indizes leiden jedoch nicht unter diesem Problem, da ihre Schlüsselwerte als Zeiger zurück auf den Clustered-Index in Nonclustered-Indizes kopiert werden. Und Schlüsselwerte bleiben gleich, auch wenn sich ihr physischer Standort ändert.

Siehe auch:

  • Der Abschnitt "Verwalten von Heaps" auf der Microsoft Docs-Seite für Heaps (Tabellen ohne Clustered-Indizes) :

    Erstellen Sie einen gruppierten Index auf dem Heap, und löschen Sie dann den gruppierten Index, um einen Heap neu zu erstellen, um verschwendeten Speicherplatz zurückzugewinnen.

  • Der Abschnitt "Überlegungen zur Verwendung der Zeilen- und Seitenkomprimierung" auf der Microsoft Docs-Seite für die Datenkomprimierung :

    Wenn ein Heap für die Komprimierung auf Seitenebene konfiguriert ist, erhalten Seiten die Komprimierung auf Seitenebene nur auf folgende Arten:

    • Daten werden mit aktivierten Bulk-Optimierungen massenweise importiert.
    • Daten werden mit der INSERT INTO ... WITH (TABLOCK) -Syntax eingefügt, und die Tabelle hat keinen Nonclustered-Index.
    • Eine Tabelle wird durch Ausführen der Anweisung ALTER TABLE ... REBUILD mit der Option PAGE compression neu erstellt.

    Und die Aussage in der Frage zitiert.

Solomon Rutzky
quelle