Mittwoch, 19. März 2014

Wie viele Datensätze passen auf eine Datenseite

Es versteht sich von selbst, dass diese Frage eher akademischer Natur ist und mehr dem Spaß am Ausprobieren gewidmet ist. Dennoch wurde diese Frage auf LinkedIn gestellt (http://tinyurl.com/q4zuxzc) und ich habe mir einfach mal die Arbeit gemacht, dieser Frage – aus rein akademischer Neugier – nachzugehen. Wer wissen möchte, wie viele Datensätze maximal auf eine Datenseite in einer Datenbank von Microsoft SQL Server 2012 passen, dem wünsche ich viel Spaß beim Lesen.

Struktur einer Datenseite

DataPage_01Eine Datenseite in Microsoft SQL Server hat immer eine Größe von 8.192 Bytes. Von diesen 8.192 Bytes sind 96 Bytes ausschließlich für den Header reserviert. Somit stehen 8.060 Bytes für die Speicherung von Daten zur Verfügung. Die Informationen über den Offset, an dem ein Datensatz auf einer Datenseite beginnt, werden im sogenannten Slot Array gespeichert. Für die Speicherung des Offset eines Datensatzes werden 2 Bytes benötigt!

Der Slot Array ist von großer Bedeutung, da die Datensätze von Microsoft SQL Server nicht zwischen bestehende Datensätze “sortiert” werden sondern – um möglichst schnell die Operation zu beenden – in einem Bereich, in den der Datensatz vollständig gespeichert werden kann. Anschließend wird das Offset mit den Informationen über den Beginn des Datensatzes im Slot Array hinterlegt um schnell auf den Datensatz in der Datenseite zugreifen zu können.

Struktur eines Datensatzes

Ein auf einer Datenseite gespeicherter Datensatz besteht nicht nur aus den Daten selbst sondern zusätzlich weitere Informationen über die Art des Datensatzes (Status), Spaltenzahl, Werte, etc. Die nachfolgende Aufzählung listet nur die Informationen auf, die in jeder Datensatzstruktur vorkommen.

  • 2 Bytes für den Datensatztypen und den Datensatzstatus
  • 2 Bytes für die Länge der Daten, die in Attributen mit fester Länge gespeichert werden
  • 2 Bytes für die Speicherung der Anzahl aller Attribute des Datensatzes
  • 2 Bytes für das NULL-Bitmap und die Anzahl der Attribute mit variabler Länge

Mögliche Anzahl von Datensätzen

Ausgehend von einer Tabelle mit einem Attribut von einem Datentypen, der nur 1 Byte benötigt (tinyint, byte) sieht die Gesamtlänge eines einzelnen Datensatzes wie folgt aus:

  • 8 Bytes für die Datensatzstruktur
  • 1 Byte für die Speicherung des Datenwerts
  • 2 Bytes für die Speicherung des Slot Arrays

Insgesamt hat ein solcher Datensatz – intern – eine Länge von 11 Bytes. Verteilt man die verbleibenden 8.060 Bytes auf die möglichen Datensätze, könnten 732 Datensätze gespeichert werden – rein rechnerisch; mal sehen, was der nachfolgende Test bringt…

Test

Das folgende Script erstellt eine Tabelle mit einem Attribut [C1] vom Datentypen [tinyint]. Das ist – neben dem Datentypen [bit] – der kleinste Datentyp und benötigt 1 Byte für die Speicherung von Daten.

CREATE TABLE dbo.little_table
(c1    tinyint    DEFAULT (1));
GO
 
-- 732 Datensätze in die Tabelle eintragen
INSERT INTO dbo.little_table DEFAULT VALUES;
GO 732
 
-- Anzeige der physikalischen Position
SELECT  *
FROM    dbo.little_table
        CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%);
FN_PHYSLOCCRACKER_01

Das Ergebnis ist etwas überraschend. Der letzte belegte Slot auf der Datenseite 26.466 ist der Slot 700 und nicht – wie berechnet – 732! Der Datensatz 701 wird auf der Datenseite 24.468 weiter geführt.


Eine Datenseite in Microsoft SQL Server 2012 speichert nicht zwingend so lange Informationen, bis die Seite vollständig gefüllt ist sondern maximal 700 Datensätze. Berücksichtigt man die Tatsache, dass Datensätze in Microsoft SQL Server in der Regel eine Länge von mehr als 1 Byte besitzen, dürfte diese “Grenze” wohl nie erreicht werden.


Wie viel Platz ist auf der Datenseite noch vorhanden?


Wenn 700 Datensätze auf der Datenseite gespeichert wurden, statt – wie berechnet – 732, sollte auf der Datenseite noch ausreichend Platz vorhanden sein. Ein Blick auf den Header der Datenseite zeigt die Details:



DBCC TRACEON (3604);
DBCC PAGE ('demo_db', 1, 26466, 1);

DBCC_PAGE_01


Die obige Abbildung zeigt den Header der Datenseite. Es stehen insgesamt noch 396 Bytes an freiem Speicher zur Verfügung. Dieser Wert errechnet sich wie folgt:


8.192 Bytes – (700 * 2 Bytes) – 6.396 Bytes (Offset des nächsten freien Bereichs) = 396 Bytes


Obwohl also noch ausreichend Platz zur Verfügung steht, werden von Microsoft SQL Server nicht mehr als 700 Datensätze auf eine Datenseite gespeichert. Sollte als mal in einer Diskussionsrunde diese Frage auftauchen so lautet die Antwort nicht “42” sondern “700”


Herzlichen Dank fürs Lesen!

Kommentare :

  1. Andreas Wolter hat sich ebenfalls mit dieser Frage beschäftigt und meine Behauptung beeindruckend widerlegt. Tatsächlich passen nämlich deutlich mehr Datenzeilen auf eine Datenseite!

    http://www.insidesql.org/blogs/andreaswolter/2014/10/maximale-anzahl-zeilen-je-datenseite-max-row-data-page-in-sql-server

    Nach dem Neuaufbau des Heaps wären sauber alle Datensätze auf einer Datenseite gelandet.
    Danke an Andreas für die - beeindruckende - Korrektur meiner Aussage.

    AntwortenLöschen
  2. Hallo Uwe
    vielen Dank für den Verweis.
    Man sieht sich in Seattle.

    AntwortenLöschen