Warum wird in SQL Server ein tinyint mit 9B in der Zeile gespeichert? Aus irgendeinem Grund scheint es am Ende der NULL-Bitmap-Maske ein zusätzliches Byte zu geben.
USE tempdb; GEHEN CREATE TABLE tbl ( i TINYINT NICHT NULL ); GEHEN INSERT IN tbl (i) WERTE (1); GEHEN DBCC IND ('tempdb', 'tbl', - 1); GEHEN DBCC TRACEON (3604); - Page Dump wird die Konsole gehen GEHEN DBCC PAGE ('tempdb', 1,168,3); GEHEN
Ergebnisse (Ich habe die Bytes umgekehrt, da DBCC-PAGEs das niedrigstwertige Byte zuerst anzeigen):
Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count = 0x0001 = 2B
NULL Bitmap = 0x0000 = 2B (what!?)
sql-server-2008
outwire
quelle
quelle
Antworten:
Wenn Sie den Datensatz mit der einfachen Größenaddition berechnen, erhalten Sie in der Tat 8: 4 + 1 + 2 + 1 (Header + feste Größe + Null-Bitmap-Anzahl + Null-Bitmap selbst). Aber ein Haufen Datensatz kann nicht kleiner sein als die Forwarding - Stub Größe , die 9 Byte ist, da der Datensatz muss gewährleisten , dass sie mit einer Spedition Stummel ersetzt werden kann. Daher wird der Datensatz tatsächlich 9 Bytes lang sein. A
smallint
wird 9 Bytes sein, sowohl durch Berechnung als auch durch minimale Größe. Alles, was größer ist, ist bereits größer als der Weiterleitungsstub, sodass Ihre Rechengröße der Datensatzgröße entspricht.quelle
CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)
Ist es also nur eine allgemeine Regel für alle Zeilen, ob sie Teil eines Heaps sind oder nicht?alter table ... drop constraint
) umgewandelt werden, und die Operation ist keine vollständige Neuerstellung (die oberen Seiten des B-Baums werden weggeworfen, die verbleibenden Blattseiten werden nicht verknüpft und das Ergebnis ist der Heap), sodass die Reservierungslogik weiterhin gültig ist .Es ist schön, das Ohr des Autors zu haben. :-) Kalen vermutet, dass dies nur die Durchsetzung einer Art Mindestreihenlänge ist, bei der alles <9 bis 9 aufgefüllt ist. Natürlich gibt es nur wenige Fälle, in denen dies möglich ist. Sie finden dieses Phantombyte für TINYINT und BIT sowie VARCHAR (1) / CHAR (1). Sie steigt nicht über 9 hinaus, wenn Sie zu SMALLINT oder CHAR (2) wechseln. Sie steigt jedoch, wenn Sie beispielsweise zu CHAR (3) wechseln.
Im Wesentlichen können Sie also auf die Effizienz hinweisen, die Sie durch eine sorgfältige Auswahl der Datentypen erzielen können. Es gibt jedoch auch einige Randfälle, in denen die Regeln aufgrund anderer Faktoren auf der Speicherebene nicht gelten.
EDIT Ich hoffe, genauere Informationen für Sie zu haben. Ich wollte Sie nur wissen lassen, dass dies der Autor des Internals-Buches ist. Sie ist nicht 100% sicher.
quelle