Ich habe die folgende Tabelle erstellt:
CREATE TABLE dbo.TestStructure
(
id INT NOT NULL,
filler1 CHAR(36) NOT NULL,
filler2 CHAR(216) NOT NULL
);
und erstellte dann einen gruppierten Index:
CREATE CLUSTERED INDEX idx_cl_id
ON dbo.TestStructure(id);
Als nächstes habe ich es mit 30 Zeilen bestückt, jede Größe ist 256 Byte (basierend auf der Tabellendeklaration):
DECLARE @i AS int = 0;
WHILE @i < 30
BEGIN
SET @i = @i + 1;
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (@i, 'a', 'b');
END;
Basierend auf Informationen, die ich im Buch "Training Kit (Prüfung 70-461): Abfragen von Microsoft SQL Server 2012 (Itzik Ben-Gan)" gelesen habe:
SQL Server organisiert intern Daten in einer Datendatei in Seiten. Eine Seite ist eine 8-KB-Einheit und gehört zu einem einzelnen Objekt. Zum Beispiel zu einer Tabelle oder einem Index. Eine Seite ist die kleinste Lese- und Schreibeinheit. Die Seiten sind weiter in Bereiche unterteilt. Ein Umfang besteht aus acht aufeinander folgenden Seiten. Seiten aus einer Ausdehnung können zu einem einzelnen Objekt oder zu mehreren Objekten gehören. Wenn die Seiten zu mehreren Objekten gehören, wird die Ausdehnung als gemischte Ausdehnung bezeichnet. Wenn die Seiten zu einem einzelnen Objekt gehören, wird die Ausdehnung als einheitliche Ausdehnung bezeichnet. SQL Server speichert die ersten acht Seiten eines Objekts in gemischten Ausmaßen. Wenn ein Objekt mehr als acht Seiten umfasst, weist SQL Server diesem Objekt zusätzliche einheitliche Bereiche zu. Mit dieser Organisation verschwenden kleine Objekte weniger Platz und große Objekte sind weniger fragmentiert.
Hier habe ich also die erste 8-KB-Seite mit gemischtem Umfang, die mit 7680 Bytes gefüllt ist (ich habe eine Zeile mit 30 mal 256 Bytes eingefügt, also 30 * 256 = 7680), um die Größe zu überprüfen, die ich beim Größenprüfprozess ausgeführt habe. Es wird das folgende Ergebnis zurückgegeben
index_type_desc: CLUSTERED INDEX
index_depth: 1
index_level: 0
page_count: 1
record_count: 30
avg_page_space_used_in_percent: 98.1961947121324
name : TestStructure
rows : 30
reserved : 16 KB
data : 8 KB
index_size : 8 KB
unused : 0 KB
So sind 16 KB für die Tabelle reserviert, die erste 8-KB-Seite ist für die Root-IAM-Seite, die zweite für die Blattdatenspeicherseite, die 8 KB mit einer Belegung von ~ 7,5 KB hat. Jetzt füge ich eine neue Zeile mit 256 Byte ein:
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');
es wird nicht auf derselben Seite gespeichert, obwohl es einen Speicherplatz von 256 Byte hat (7680 b + 256 = 7936, was immer noch kleiner als 8 KB ist), eine neue Datenseite wird erstellt, aber diese neue Zeile könnte auf dieselbe alte Seite passen Warum erstellt SQL Server eine neue Seite, wenn dies Platz und Zeit spart, wenn Sie sie in die vorhandene Seite einfügen?
Hinweis: Dasselbe passiert im Heap-Index.