SQL SERVER Archiviazione di TinyInt


12

In SQL Server, perché è un tinyint memorizzato con 9B nella riga. Per qualche motivo sembra che ci sia un ulteriore byte alla fine della maschera bitmap NULL.

    USA tempdb;
    PARTIRE

    CREA TABELLA tbl
    (
        I TINYINT NON NULL
    );
    PARTIRE

    INSERISCI IN tbl (i)
        VALORI (1);
    PARTIRE

    DBCC IND ('tempdb', 'tbl', - 1);
    PARTIRE

    DBCC TRACEON (3604); - Il dump della pagina andrà alla console
    PARTIRE

    DBCC PAGE ('tempdb', 1.168,3);
    PARTIRE

Risultati (ho invertito i byte a causa della PAGINA DBCC che mostra prima il byte meno significativo):

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!?)

1
È solo educativo? Sono tutto per tagliare lo spazio dove necessario, ma questo probabilmente non è il 1 byte di cui mi preoccuperò ...
Aaron Bertrand

Questo è educativo. Il mio prossimo discorso su SQLSaturday è su compressin; così, ho creato esempi per ogni tipo di dati per aiutare le persone a comprendere le implicazioni delle scelte dei loro tipi di dati e per mostrare l'effetto della compressione su tutti i tipi di dati.
outwire

Supponevo che tinyint sarebbe stato memorizzato come 1B (lo è) con 7B di sovraccarico. Mi chiedo quale sia il byte extra alla fine della registrazione ???
outwire

Vedo risultati diversi (anche se non sono sicuro che siano più in linea con ciò che ti aspetti) quando la colonna TINYINT non è l'unica colonna della tabella. Sembra un caso d'uso piuttosto raro.
Aaron Bertrand

Certamente non è una preoccupazione comune del caso d'uso. Stavo solo cercando di mostrare ogni tipo di dati da solo per portare a casa sia i costi generali di archiviazione che per far vedere ai principianti come appare la colonna sulla pagina. Trovo strano avere il byte in più ... mi fa impazzire vederlo lì e senza motivo.
outwire

Risposte:


12

Se si calcola il record utilizzando l'aggiunta di dimensioni semplici, si ottiene effettivamente 8: 4 + 1 + 2 + 1 (intestazione + dimensione fissa + conteggio bitmap null + bitmap stesso). Ma un record di heap non può essere inferiore alla dimensione dello stub di inoltro , che è di 9 byte, poiché il record deve garantire che può essere sostituito con uno stub di inoltro. Quindi, il record sarà in realtà di 9 byte. A smallintsarà di 9 byte sia per il calcolo che per la dimensione minima. Qualunque cosa più grande è già più grande dello stub di inoltro, quindi la dimensione del tuo calcolo corrisponde alla dimensione del record.


I 9 byte si applicano anche a questa definizione, CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)quindi è solo una regola generale per tutte le righe indipendentemente dal fatto che facciano parte di un heap?
Martin Smith,

1
Il b-tree può essere trasformato in un heap ( alter table ... drop constraint) e l'operazione non è una ricostruzione completa (le pagine superiori del b-tree vengono gettate via, le pagine delle foglie lasciate non collegate e il risultato è l'heap) quindi la logica di prenotazione si applica ancora .
Remus Rusanu,

Penso che questo provi ciò che Remus ha dichiarato ... migliorare.dk/archive/2011/06/07/…
ooutwire

6

È bello avere l'orecchio dell'autore. :-) Kalen sospetta che si tratti solo di applicare una sorta di lunghezza minima della riga, dove qualsiasi cosa <9 è imbottita a 9. Naturalmente ci sono solo pochi casi in cui ciò è possibile. Troverai questo byte fantasma per TINYINT e BIT e VARCHAR (1) / CHAR (1). Non aumenterà oltre 9 se passi a SMALLINT o CHAR (2), ma aumenterà se passi a, diciamo, CHAR (3).

Quindi, in sostanza, puoi evidenziare l'efficienza che puoi ottenere scegliendo saggiamente i tipi di dati, ma sottolinea che ci sono alcuni casi limite in cui le regole non valgono a causa di altri fattori a livello di storage.

EDIT Spero di avere informazioni più concrete per te. Volevo solo farti sapere che questo è ciò che l'autore del libro Internals attualmente pensa. Non è sicura al 100%.


Grazie Aaron per aver contattato Kalen. Ieri sera stavo sfogliando quel libro e mi stavo togliendo i capelli. Questo è un po 'come i byte di metadati extra per sql_variant, tranne che qui non ho modo di spiegare il byte fantasma tranne che per agitare la mano e gridare "È così che è amico!"
outwire

1
Bene, puoi associare quel commento a "questo è un caso limite estremo, dal momento che non molte tabelle sono mai progettate per provare a memorizzare un singolo minuscolo o carattere (1) in ogni riga".
Aaron Bertrand
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.