Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:SQL Server
Azure SQL-Datenbank
Verwaltete Azure SQL-Instanz
SQL-Datenbank in Microsoft Fabric
Ein Heap ist eine Tabelle ohne gruppierten Index. Man kann einen oder mehrere nicht-geclusterte Indizes auf Tabellen erstellen, die als Heap gespeichert sind. Der Heap speichert Daten, ohne eine Reihenfolge anzugeben. Normalerweise speichert der Heap zunächst die Daten in der Reihenfolge, in der du die Zeilen einfügst. Die Datenbank-Engine kann Daten jedoch im Heap verschieben, um die Zeilen effizient zu speichern. Bei Abfrageergebnissen kann man die Datenreihenfolge nicht vorhersagen. Um die von einem Heap zurückgegebene Zeilenreihenfolge zu garantieren, verwenden Sie die ORDER BY-Klausel. Um eine dauerhafte logische Reihenfolge für die Speicherung der Zeilen festzulegen, erstelle einen clusterten Index in der Tabelle, damit die Tabelle kein Heap ist.
Note
Manchmal gibt es gute Gründe, eine Tabelle als Heap zu belassen, anstatt einen Cluster-Index zu erstellen. Der effektive Einsatz von Heaps ist jedoch eine fortgeschrittene Fähigkeit. Die meisten Tabellen sollten über einen sorgfältig ausgewählten gruppierten Index verfügen, es sei denn, es gibt gute Gründe, die Tabelle als Heap beizubehalten.
Wann man einen Heap verwendet
Ein Heap ist ideal für Tabellen, die man häufig abschneidet und neu lädt. Die Datenbank-Engine optimiert den Speicherplatz in einem Heap, indem sie den frühestmöglichen verfügbaren Speicherplatz füllt.
Beachte Folgendes:
- Freier Speicherplatz in einem Heap zu finden, kann teuer sein, besonders wenn viele Löschungen oder Aktualisierungen stattfinden.
- Geclusterte Indizes bieten eine stabile Performance für Tabellen, die man nicht häufig abschneidet.
Für Tabellen, die du regelmäßig abschneidest oder neu erstellst, wie temporäre oder Staging-Tabellen, ist die Verwendung eines Heaps oft effizienter.
Die Wahl zwischen dem Einsatz eines Heaps und eines gruppierten Indexes kann sich erheblich auf die Leistung und Effizienz Ihrer Datenbank auswirken.
Wenn Sie eine Tabelle als Heap speichern, identifizieren Sie einzelne Zeilen anhand einer 8-Byte-Zeilenkennung (RID), die aus Dateinummer, Datenseitennummer und Slot auf der Seite besteht (FileID:PageID:SlotID). Die Zeilen-ID ist eine kleine und effiziente Struktur.
Verwenden Sie Heaps als Staging Tables für große, ungeordnete Einfügungsoperationen. Da Heaps keine strikte Einfügungsreihenfolge durchsetzen, ist die Einfügungsoperation in der Regel schneller als eine äquivalente Einfügung in einen Cluster-Index. Wenn Sie die Daten des Heaps lesen und zu einem endgültigen Ziel verarbeiten, sollten Sie in Erwägung ziehen, einen schmalen, nicht-geclusterten Index zu erstellen, der das Suchprädikat abdeckt, das die Abfrage verwendet.
Note
Man holt Daten aus einem Heap in der Reihenfolge der Datenseiten ab, aber nicht unbedingt in der Reihenfolge, in der man die Daten eingefügt hat.
Man kann auch Heaps verwenden, wenn man immer auf Daten über nicht-geclusterte Indizes zugreift und der RID kleiner ist als ein Cluster-Indexschlüssel.
Wenn eine Tabelle ein Heap ist und keine nicht-geclusterten Indizes enthält, musst du die gesamte Tabelle (ein Tabellenscan) lesen, um eine beliebige Zeile zu finden. SQL Server kann keinen RID direkt auf dem Heap suchen. Dieses Verhalten kann akzeptabel sein, wenn die Tabelle klein ist.
Keine Verwendungsbereiche für Heaps
Verwenden Sie keinen Heap, wenn die Daten häufig in sortierter Reihenfolge zurückgegeben werden. Ein geclusterter Index in der Sortierspalte kann die Sortieroperation vermeiden.
Verwenden Sie keinen Heap, wenn die Daten häufig gruppiert sind. Die Daten müssen vor der Gruppierung sortiert werden, und ein geclusterter Index in der Sortierspalte kann die Sortieroperation vermeiden.
Verwenden Sie keinen Heap, wenn häufig Datenbereiche aus der Tabelle abgefragt werden. Mit einem gruppierten Index für die Bereichsspalte kann der Sortiervorgang für den gesamten Heap vermieden werden.
Verwenden Sie keinen Heap, wenn keine nicht-geclusterten Indizes vorhanden sind und die Tabelle groß ist. Die einzige Anwendung dieses Designs besteht darin, den gesamten Tabelleninhalt ohne angegebene Reihenfolge zurückzugeben. In einem Heap liest die Datenbank-Engine alle Zeilen, um eine beliebige Zeile zu finden.
Verwende keinen Heap, wenn du die Daten häufig aktualisierst. Wenn Sie einen Datensatz aktualisieren und das Update mehr Speicherplatz auf den Datenseiten benötigt als aktuell, wird der Datensatz auf eine Datenseite verschoben, die genug freien Speicherplatz hat. Dieser Move erzeugt einen weitergeleiteten Datensatz , der auf den neuen Speicherort der Daten zeigt. Der Weiterleitungszeiger wird auf der Seite geschrieben, auf der zuvor die Daten gehalten wurden, um den neuen physischen Standort anzuzeigen. Dieser Move führt zu Fragmentierung im Heap. Wenn die Datenbank-Engine einen Heap durchsucht, folgt er diesen Zeigern. Diese Aktion begrenzt die Read-Ahead-Leistung und kann zusätzliche I/O verursachen, was die Scan-Leistung verringert.
Verwalten von Heaps
Erstellen Sie zum Anlegen eines Heaps eine Tabelle ohne gruppierten Index. Wenn eine Tabelle bereits einen gruppierten Index hat, löschen Sie den gruppierten Index, um die Tabelle wieder in einen Heap zurückzuversetzen.
Erstellen Sie zum Löschen eines Heaps auf dem Heap einen gruppierten Index.
So erstellen Sie einen Heap neu, um nicht verwendeten Speicherplatz freizugeben:
- Erstellen Sie auf dem Heap einen clustered Index, und löschen Sie ihn dann wieder.
- Verwenden Sie den Befehl
ALTER TABLE ... REBUILD, um den Heap neu zu erstellen.
Warning
Das Erstellen oder Löschen von gruppierten Indizes erfordert, dass die gesamte Tabelle neue geschrieben werden muss. Wenn die Tabelle nicht-geclusterte Indizes hat, müssen Sie alle nicht-geclusterten Indizes neu erstellen, sobald Sie den geclusterten Index ändern. Daher kann der Wechsel von einem Heap zu einer clusterierten Indexstruktur oder zurück viel Zeit in Anspruch nehmen und Speicherplatz für die Neuordnung der Daten in tempdbbenötigen.
Identifizieren von Heaps
Die folgende Abfrage gibt die Liste der Heaps aus der aktuellen Datenbank zurück. Die Liste enthält:
- Tabellennamen
- Namen der Schemata
- Anzahl der Zeilen
- Tabellengröße in KB
- Indexgröße in KB
- Nicht verwendeter Speicherplatz
- Eine Spalte zum Identifizieren eines Heaps
SELECT t.name AS 'Your TableName',
s.name AS 'Your SchemaName',
p.rows AS 'Number of Rows in Your Table',
SUM(a.total_pages) * 8 AS 'Total Space of Your Table (KB)',
SUM(a.used_pages) * 8 AS 'Used Space of Your Table (KB)',
(SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS 'Unused Space of Your Table (KB)',
CASE
WHEN i.index_id = 0 THEN 'Yes'
ELSE 'No'
END AS 'Is Your Table a Heap?'
FROM sys.tables AS t
INNER JOIN sys.indexes AS i
ON t.object_id = i.object_id
INNER JOIN sys.partitions AS p
ON i.object_id = p.object_id
AND i.index_id = p.index_id
INNER JOIN sys.allocation_units AS a
ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.schemas AS s
ON t.schema_id = s.schema_id
WHERE i.index_id <= 1 -- 0 for Heap, 1 for Clustered Index
GROUP BY t.name, s.name, i.index_id, p.rows
ORDER BY 'Your TableName';
Heapstrukturen
Ein Heap ist eine Tabelle ohne gruppierten Index. Heaps haben eine Zeile in sys.partitions, mit index_id = 0 für jede vom Heap verwendete Partition. Standardmäßig verfügt ein Heap über eine einzelne Partition. Wenn ein Heap über mehrere Partitionen verfügt, hat jede Partition eine Heapstruktur, in der die Daten für die jeweilige Partition enthalten sind. Wenn ein Heap z. B. über vier Partitionen verfügt, gibt es vier Heapstrukturen – jeweils eine in jeder Partition.
Je nach Datentypen im Heap verfügt jede Heap-Struktur über eine oder mehrere Allokationseinheiten, um die Daten für eine bestimmte Partition zu speichern und zu verwalten. Mindestens hat jeder Heap eine Zuteilungseinheit IN_ROW_DATA pro Partition. Die Heap-Struktur hat außerdem eine Zuweisungseinheit LOB_DATA pro Partition, wenn sie große Objekt- (LOB-)Spalten enthält. Es gibt außerdem eine Zuteilungseinheit ROW_OVERFLOW_DATA pro Partition, wenn sie variabel länge-Spalten enthält, die die Zeilengrößengrenze von 8.060 Bytes überschreiten.
Die Spalte first_iam_page in der sys.system_internals_allocation_units Systemansicht verweist auf die erste Index Allocation Map (IAM)-Seite in der Kette der IAM-Seiten, die den dem Heap in einer bestimmten Partition zugewiesenen Speicherplatz verwalten. SQL Server verwendet die IAM-Seiten, um sich durch den Heap zu bewegen. Die Datenseiten und die Zeilen darin sind in keiner bestimmten Reihenfolge und nicht verknüpft. Die einzige logische Verbindung zwischen den Datenseiten sind die Informationen, die auf den IAM-Seiten aufgezeichnet sind.
Important
Die sys.system_internals_allocation_units Systemansicht ist ausschließlich für die interne Nutzung reserviert. Zukünftige Kompatibilität wird nicht garantiert.
Man kann Tabellenscans oder serielle Lesungen eines Heaps durchführen, indem man die IAM-Seiten scannt, um die Extents zu finden, die Seiten für den Heap enthalten. Da das IAM Extents in derselben Reihenfolge repräsentiert, in der sie in den Datendateien existieren, bedeutet diese Struktur, dass serielle Heap-Scans den Fortschritt sequentiell durch jede Datei durchlaufen. Die Verwendung der IAM-Seiten zur Einstellung der Scansequenz bedeutet auch, dass Zeilen aus dem Heap typischerweise nicht in der Reihenfolge zurückgegeben werden, in der sie eingefügt wurden.
Die folgende Abbildung zeigt, wie die SQL Server-Datenbank-Engine die IAM-Seiten zum Abrufen von Datenzeilen in einem Heap mit einer einzelnen Partition verwendet.