it-swarm.it

Quando utilizzare TINYINT su INT?

In generale, utilizzo sempre Ints. So che in teoria questa non è la migliore pratica, dal momento che dovresti usi il tipo di dati più piccolo che ti sarà garantito per archiviare i dati.

Ad esempio, è meglio usare tinyint quando si sa che gli unici dati che verranno archiviati sono 1, 0 o null (con una probabilità molto piccola di estenderli a 2 o 3 in seguito).

Tuttavia, l'unico motivo che conosco per fare questo è per scopi di archiviazione - utilizzando 1 byte su una riga anziché 4 byte.

Quali sono gli impatti dell'utilizzo di tinyint (o smallint o anche bigint) solo su int, oltre a risparmiare spazio sul disco rigido?

92
Richard

Lo spazio su disco è economico ... non è questo il punto!

Smetti di pensare in termini di spazio di archiviazione, pensa invece al pool di buffer e larghezza di banda di archiviazione . All'estremo, cache della CPU e larghezza di banda del bus di memoria . L'articolo collegato fa parte della serie che evidenzia problemi con una scarsa selezione della chiave cluster (INT vs GUID vs GUID sequenziale) ma evidenzia la differenza che i byte possono fare.

Il messaggio prioritario riguarda le questioni di progettazione. La differenza non verrà visualizzata in un singolo database su un server adeguatamente specificato fino a quando non si raggiunge il territorio VLDB ma se è possibile salvare alcuni byte, perché non farlo.

Mi viene in mente l'ambiente descritto in un domanda precedente . Oltre 400 database, di dimensioni variabili da 50 MB a 50 GB, per istanza SQL. Scrubbing di pochi byte per record, per tabella, per database in quell'ambiente potrebbe fare una differenza significativa.

92

Oltre alle altre risposte ...

Le righe e le voci di indice sono memorizzate in 8k pagine. Quindi un milione di righe a 3 byte per riga non è 3 MB sul disco: influisce sul numero di righe per pagina ("densità di pagina").

Lo stesso vale per nvarchar a varchar, smalldatetime a datetime, int a tinyint ecc

Modifica, giugno 2013

http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx

Questo articolo afferma

I criteri importanti sono la cardinalità e il rapporto da pagina a riga.

Quindi, la scelta del tipo di dati è importante

29
gbn

Non è solo l'archiviazione di tabelle che è una considerazione. Se usi gli indici in cui la colonna int fa parte di una chiave composta, vorrai naturalmente che le pagine dell'indice siano il più complete possibile, dato che le voci dell'indice sono le più piccole possibili.

Mi sarei sicuramente aspettato di scoprire che esaminare le voci dell'indice nelle pagine BTREE sarebbe un po 'più veloce con tipi di dati più piccoli. Tuttavia, qualsiasi VARCHAR coinvolto nelle voci di indice compenserebbe (annullerebbe) i guadagni di prestazione dall'uso di TINYINT su INT.

Ciononostante, se le voci di indice hanno voci composte e tutte sono numeri interi, più piccoli sono i numeri a byte, meglio è e più velocemente.

14
RolandoMySQLDBA

Tutto diventa più complesso quando i database diventano più grandi:

  • le finestre di manutenzione devono essere ingrandite o riprogrammate
  • backup (il backup completo di fine giornata diventa un assurdo dispendio di tempo, quindi è necessario un backup differenziale o addirittura log e fare l'intero una volta alla settimana, forse una volta al mese)
  • le manutenzioni delle prestazioni diventano un dispendio di tempo (la creazione di un indice su una tabella multi-milione di righe non richiede poco tempo per l'esecuzione) e deve essere riprogrammata e peggiora se la tabella è ampia ...
  • E trasmettere quel backup da 100 Gb attraverso la rete non è ciò che chiamo un gioco da ragazzi - specialmente se la rete (per qualche ragione sconosciuta) è testarda a lasciare cadere la connessione sul segno da 75 Gb ... (è successo con un'installazione che stavo lavorando che stava eseguendo il backup su un'unità mappata sulla rete - rete) ...

E quali tipi di dati hanno a che fare con questo? TUTTO. L'uso di dimensioni di riga maggiori del necessario consente di riempire le pagine del database prima del necessario o addirittura di sprecare spazio se le dimensioni delle righe sono tali che non è possibile registrare più di un record sulla pagina. Il risultato sono più pagine necessarie per scrivere e leggere, più RAM viene utilizzata per memorizzarla nella cache (i record più grandi richiedono memoria maggiore). E poiché i tipi di dati sono specificati più grandi del necessario dal disco, gli indici subirà lo stesso problema, specialmente se si raggruppa quella chiave primaria composita di 2 colonne BIGINT poiché qualsiasi altro indice creato copierà implicitamente quella chiave primaria sulla loro definizione.

Se sai che alcune colonne in una tabella che avranno milioni di righe o addirittura una piccola tabella che verranno convertite in più milioni di righe che non richiedono un numero intero di 4 byte per memorizzare i loro dati, ma un 2 byte basti - usa SMALLINT . Se i valori nell'intervallo 0-255 sono sufficienti, TINYINT . Una bandiera sì/no? C'è BIT .

13
Fabricio Araujo

Mentre per tinyint vs int ci sono chiare differenze come spazio su disco, suddivisioni di pagina e tempi di manutenzione, non ci sarebbe nessuna di queste per varchar.

Quindi perché non dichiarare tutti i campi di testo come varchar(4000), poiché utilizzerà comunque solo lo spazio necessario? Ancora di più ti verrà garantito che i tuoi dati non verranno mai troncati.

La risposta è ovviamente:

  1. Chiarimento delle tue intenzioni (poiché nessuno capirà perché un campo nome dovrebbe contenere 4000 caratteri)
  2. Convalida come vuoi assicurarti che nessuno inserisca un'intera biografia come nome.

Questi stessi motivi si applicano anche a tinyint.

9
yoel halb