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.