Le colonne vuote occupano spazio in una tabella?


20

Ho una tabella che contiene informazioni di base. Solo un titolo e alcuni campi della data. C'è un campo chiamato commenti che è varchar (4000) Il più delle volte lo lasciamo vuoto, ma alcune volte inseriremo una grande quantità di dati qui. È davvero un brutto design? O è solo leggermente inefficiente?

Suppongo che sarebbe meglio creare una tabella separata per questa colonna.

nota: questo è SQL Server 2008

inserisci qui la descrizione dell'immagine


Grazie per il tuo feedback a tutti! Ho deciso di mantenerlo semplice e mantenere la colonna nella tabella e non inserirla in un'altra tabella. Tuttavia, ho utilizzato la funzionalità SPARSE in SQL 2008, quindi il campo non utilizza spazio.

2
Solo curioso, che cos'è "il più delle volte"? Quante righe totali e quale percentuale ha un valore qui? Mi chiedo solo se stai pianificando di fare confronti di spazio / prestazioni usando SPARSEe non usando SPARSE...
Aaron Bertrand

Risposte:


9

Per prestazioni più prevedibili (e per evitare una variazione elevata delle righe per pagina), mi affiderei alla memorizzazione di questi dati in una tabella correlata, soprattutto se vengono popolati solo una piccola percentuale del tempo e soprattutto se vengono recuperati solo in alcune delle domande. Le righe in cui si trova questo valore NULLcontribuiscono al sovraccarico di spazio, ma questo è minimo. Più importante sarà il modo in cui una pagina può contenere solo due righe e la pagina successiva può contenere 500 righe: questo può davvero influire sulle statistiche e potresti essere meglio suddividendolo in modo che sia memorizzato separatamente e non influisca su tutte le tue operazioni la tabella principale.


12

Ci vuole uno spazio minimo quando non utilizzato

  • un bit nella bitmap NULL
  • due byte per la lunghezza (che sarà zero quando NULL)

Il sovraccarico è minimo e l'ottimizzazione sarà prematura.

Fino a quando non sai di avere un problema, tienilo in una tabella. Interrompi KISS introducendo join esterni e aggiungi un sovraccarico nell'interrogazione dei dati.

Vedi /programming/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 per ulteriori informazioni


10

Penso che una tabella separata sarebbe meglio per migliorare la densità della pagina e ridurre la frammentazione, soprattutto se non si popola sempre quel campo.

  • Una pagina di dati contiene circa 8000 byte
  • Hai alcune righe con diciamo 100 byte e alcune righe con oltre 4000 byte
  • Quelle lunghe righe saranno su una pagina da sole, e il resto della pagina è spazio "sprecato" che il tuo DB occupa ma che probabilmente non terrà mai i dati
  • Se aggiungi dati a quel campo lungo per un record in una pagina per lo più piena, probabilmente supererà la pagina e si tradurrà in un puntatore alla pagina con il resto del record

Tutte queste pagine e puntatori vuoti portano a prestazioni scadenti. Se possibile, normalizza quel campo.


4

Questa domanda è molto simile: le colonne vuote extra influiscono in modo significativo sulla dimensione della tabella sql?

Sembra che la risposta sia sì, occupa spazio, ma esiste un algoritmo di compressione per colonne con molti valori null.

Per quanto riguarda il design, penso che avere un tavolo esterno collegato a questo sarebbe un design più pulito. Avere una colonna con valori null frequenti rende più difficile per gli utenti del database poiché potrebbero accidentalmente utilizzare un valore null se non stanno attenti. Pertanto, il codice che utilizza il database dovrebbe contenere il controllo degli errori e diventa brutto da lì.


2
Per essere espliciti, l'algoritmo di compressione si applica solo a quelle colonne esplicitamente definite come SPARSE, non solo a "colonne con molti valori nulli".
Aaron Bertrand

2

Andrà tutto bene - è già una colonna varchar, quindi usa lo spazio solo quando contiene dati. Se avessi molte colonne a dimensione fissa nullable come int, potresti avere problemi di utilizzo dello spazio.

Per quanto riguarda metterlo in un altro tavolo, non mi preoccuperei. Puoi anche guardare usando le opzioni varchar (max) e in / out of row. Ancora una volta, probabilmente prematuro.


1
L'ottimizzazione precoce può spesso essere un vero problema, ma ciò dipende dal costo del refactoring in seguito. Se oggi sai che solo l'1% delle tue righe avrà dati in questa colonna e ti aspetti che la tabella cresca nel tempo, qual è il valore nel perseverare che i dati nella tabella attuale subiranno conseguenze solo quando ridimensioni? Sono tutto per evitare l'ottimizzazione prematura, ma c'è un punto in cui sopporto l'effetto a lungo termine di farlo.
Aaron Bertrand

@Aaron Bertrand concordato. Qui le persone pongono domande sulle prestazioni ed è facile supporre che possano avere un'app composta da milioni di file e che devono usare ogni arma nel toolkit e tenere a mente tutto ciò. D'altra parte, a volte l'utente sembra essere all'inizio di una curva di apprendimento ed è difficile chiedere loro di dedicare tempo a qualcosa che probabilmente dovrebbe essere inferiore alle loro priorità. Inoltre, con varchar (max), puoi effettivamente premere un interruttore per iniziare a memorizzare fuori dalla riga. Penso che la vera risposta qui sia "Non ci hai dato abbastanza informazioni per dare una risposta definitiva".
Cade Roux,
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.