Quali sono le migliori pratiche attuali relative al dimensionamento varchar in SQL Server?


12

Sto cercando di capire il modo migliore per decidere quanto dovrebbero essere grandi le colonne varchar, sia dal punto di vista dell'archiviazione che delle prestazioni.

Performance
Dalla mia ricerca, sembraquel varchar (max) dovrebbe essere usato solo se ne hai davvero bisogno; vale a dire, se la colonna deve contenere più di 8000 caratteri, uno dei motivi è la mancanza di indicizzazione (anche se sono un po 'sospettoso dell'indicizzazione sui campi varchar in generale. Sono piuttosto nuovo sui principi DB, quindi forse è infondato ) e compressione (più un problema di archiviazione). In effetti, in generale le persone sembrano raccomandare di usare solo ciò di cui hai bisogno, quando si fa varchar (n) .... il sovradimensionamento è negativo, perché le query devono tenere conto della dimensione massima possibile. Ma è stato anche affermato che il motore utilizzerà la metà della dimensione indicata come stima della dimensione effettiva media dei dati. Ciò implicherebbe che si dovrebbe determinare, dai dati, qual è la dimensione media, raddoppiarla e usarla come n. Per i dati con una variabilità molto bassa ma diversa da zero, questo implica un sovradimensionamento fino a 2x rispetto alla dimensione massima, che sembra molto, ma forse non lo è? Approfondimenti sarebbero apprezzati.

Archiviazione
Dopo aver letto come funziona l'archiviazione in-riga o fuori-riga e tenendo presente che l'archiviazione effettiva è limitata ai dati effettivi, in realtà mi sembra che la scelta di n abbia poco o nessun rapporto con l'archiviazione (oltre assicurandoti che sia abbastanza grande da contenere tutto). Anche l'uso di varchar (max) non dovrebbe avere alcun impatto sulla memoria. Invece, un obiettivo potrebbe essere quello di limitare la dimensione effettiva di ogni riga di dati a ~ 8000 byte, se possibile. È una lettura accurata delle cose?

Contesto
Alcuni dei dati dei nostri clienti fluttuano leggermente, quindi generalmente facciamo le colonne un po 'più larghe di quanto debbano essere, diciamo del 15-20% più grandi, per quelle colonne. Mi chiedevo se ci fossero altre considerazioni speciali; per esempio, qualcuno con cui lavoro mi ha detto di usare le taglie 2 ^ n - 1 (non ho trovato alcuna prova che sia una cosa però ...)

Sto parlando della creazione della tabella iniziale. Un cliente ci dirà che inizierà a inviarci una nuova tabella e invierà dati di esempio (o solo il primo set di dati di produzione), che esamineremo e creeremo una tabella dalla nostra parte per conservare i dati. Vogliamo preparare il tavolo dalla nostra parte per gestire le importazioni future così come ciò che è nel campione. Ma alcune file sono destinate ad allungarsi, quindi le riempiamo.

La domanda è: quanto ci sono e le linee guida tecniche?


MongoDB utilizza 2 ^ n allocazione del disco per un documento. SQL Server non utilizza questa strategia.
Michael Green,

Risposte:


19

Indipendentemente dal tipo di dati specifico, devi essere in grado di archiviare qualunque cosa l'applicazione richieda di essere memorizzata. Non è possibile specificare qualcosa di più piccolo della dimensione massima di ciò che verrà effettivamente salvato.

Inoltre, non è necessario, né si desidera, specificare una lunghezza della colonna maggiore della dimensione effettiva massima che verrà archiviata per una serie di motivi: allocazione della memoria della query, potenziale riempimento della dimensione massima della riga e non lasciare spazio per l'aggiunta di colonne in il futuro, ecc.

Vero, stringa di lunghezza variabile e colonne binarie non hanno le implicazioni di archiviazione che i tipi di dati a lunghezza fissa (stringa / binario / numerico / data / ecc.) (Sebbene, alcune di queste implicazioni possano essere annullate tramite la compressione dei dati o l'uso della SPARSEdefinizione di colonna opzione). Tuttavia, come hai sottolineato, anche se non ci sono implicazioni per l'archiviazione diretta, c'è ancora l'implicazione delle prestazioni di sopravvalutare la memoria richiesta per le query.

Sii sensibile. Usa solo ciò di cui hai bisogno. È possibile prendere in considerazione se esiste un'alta probabilità che la lunghezza della colonna debba aumentare nel prossimo futuro, ma tenere presente che è più semplice espandere la dimensione di una colonna piuttosto che ridurla. Sì, sarà coinvolto un po 'di lavoro, ma dal momento che quel lavoro è semplicemente "potenziale", mentre le implicazioni relative alle prestazioni del sovradimensionamento sono "effettive", spesso è meglio definire le colonne in base a ciò di cui hai effettivamente bisogno, non a ciò che forse-tipo -sorta pensa che potresti aver bisogno in futuro. Molti cambiamenti di cui si parla non avvengono mai e spesso i cambiamenti richiesti non possono essere previsti. Vai con quello che sai.

Invece, un obiettivo potrebbe essere quello di limitare la dimensione effettiva di ogni riga di dati a ~ 8000 byte, se possibile.

Non sono esattamente sicuro di cosa stai arrivando qui. SQL Server ti limiterà fisicamente a poco più di 8000 byte. Utilizzando tipi LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, e obsoleti TEXT, NTEXTe IMAGEtipi - consentono di andare oltre questa limitazione iniziale formato pagina, ma questo è solo per mettere un puntatore (16 o più byte, a seconda del tipo, e in funzione del dimensione del valore memorizzato off-row quando si utilizzano i MAXtipi). Il limite fisico effettivo della pagina di dati non è cambiato.

Il tuo obiettivo dovrebbe essere quello di utilizzare la minima quantità di spazio fisico per archiviare ciò che l'app / azienda deve archiviare senza rompere o troncare in modo tale che il valore incompleto perda significato o causi problemi a valle. Se hai bisogno di memorizzare un oggetto di 12.000 personaggi, usa VARCHAR(MAX)perché è quello che serve. Se stai memorizzando un numero di telefono o un codice postale, allora non sarebbe saggio da usare VARCHAR(100)e irresponsabile da usare VARCHAR(MAX).

alcuni dei dati dei nostri clienti fluttuano un po ', quindi generalmente facciamo le colonne solo un po' più larghe di quanto debbano essere, diciamo del 15-20% più grandi, per quelle colonne. Mi chiedevo se ci fossero altre considerazioni speciali;

Non tutti i sistemi hanno almeno alcuni dati che fluttuano? Qualsiasi sistema che memorizza il nome di una persona si qualificherebbe, giusto? C'è una varianza abbastanza grande nella lunghezza dei nomi. E poi hai qualcuno come Prince che va e cambia il suo nome in un simbolo e ora hai un problema completamente diverso che non è la lunghezza. Ecco come stanno le cose.

Ma, per difendere il difensore del diavolo per un momento: in che modo il valore "15-20% più grande di quanto è necessario" non può essere il valore reale necessario ? Diciamo che c'è una discussione sull'aggiunta di una nuova colonna e qualcuno suggerisce 50 caratteri, quindi qualcun altro dice: "beh, il 20% in più è 60, quindi facciamo 60 perché qualcuno potrebbe averne 60". Se è vero che un cliente potrebbe avere 60, allora 60 è, ed è sempre stato, il valore effettivo necessario e 50 ha sbagliato tutto il tempo.

Certo, sarebbe utile se ci fosse qualche indicazione sulla fonte dei dati perché:

  1. se crei "URL" 1024 e qualcuno ha bisogno di 1060, allora deve essere 1060 (allo stesso modo, se crei URL VARCHARe ricevi lamentele sul fatto che sta rovinando i caratteri Unicode che ora sono consentiti nei nomi di dominio, allora deve essere NVARCHAR), ma
  2. se qualcuno vuole aggiungere 1000 caratteri per un campo di commento 500 caratteri limite, allora ancora solo bisogno di essere 500. Le persone possono essere meno verboso nei commenti (una sfida enorme per me ;-), ma ProductSKUmeglio essere abbastanza grande per adattarsi a tutti i degli SKU del cliente.

Sto parlando della creazione della tabella iniziale. Un cliente ci dirà che inizierà a inviarci una nuova tabella e invierà dati di esempio (o solo il primo set di dati di produzione), che esamineremo e creeremo una tabella dalla nostra parte per conservare i dati. Vogliamo preparare il tavolo dalla nostra parte per gestire le importazioni future così come ciò che è nel campione. Ma alcune file sono destinate ad allungarsi, quindi le riempiamo. La domanda è: quanto ci sono e le linee guida tecniche?

Stai facendo molte ipotesi qui. Certo alcuni campi potrebbero ingrandirsi. Ma poi di nuovo, potrebbero non farlo. Oppure, alcuni potrebbero ridursi. Alcuni possono passare dall'essere non Unicode a essere Unicode (una volta che si rendono conto che il mondo sta diventando più piccolo e non si può presumere che i cognomi abbiano sempre caratteri ASCII / inglesi di base). Oppure, potrebbero smettere di inviare un campo. Oppure possono aggiungere uno o più campi in futuro. Qualsiasi combinazione di questa e altre cose. Quindi perché concentrarsi solo sulle VARCHARcolonne? Cosa succede se al momento stanno inviando un INTvalore e in un anno o due raggiungono il valore massimo e iniziano a inviare un BIGINT? Che cosa succede se hanno un campo "status" con valori da 0 a 5. Hai intenzione di assumereINTquale è "imbottito" in quanto consente la crescita, ma probabilmente dovrebbe essere TINYINT?

L'unica cosa che puoi prevedere con sicurezza è che cercare di prevedere come cambieranno i dati dei tuoi clienti sarà sbagliato più spesso di quanto sia corretto. Ed essere corretti è una questione di fortuna / coincidenza (se non di fortuna, allora vai alla lotteria;).

Quindi la linea guida è:

  1. Non perdere tempo ed energia nel cercare di rispondere a una domanda senza risposta.
  2. Invece, concentrati su come ottenere quante più informazioni possibili riguardo ai dati reali dei tuoi clienti, e segui quello (cioè il processo decisionale basato sui dati ;-).

Hai già dei dati di esempio, fantastico. Ma, per favore, non dimenticare che hai anche le informazioni di contatto del tuo cliente: telefono e / o e-mail. Contattali! Chiedi loro le specifiche dei loro dati (proprio come il tuo sistema, i dati attualmente nel loro sistema potrebbero avere una lunghezza massima di 35, ma il loro sistema ha definito come VARCHAR(50), e il loro sistema accetterà fino a quella lunghezza, nel qual caso dovresti usare 50). E chiedi loro se hanno piani a breve termine da modificare e di quei tipi di dati (tipo e / o dimensione).


1
Sono d'accordo con Solomon, @ Aristotle2600 - tuttavia, potresti voler dare un'occhiata alla mia risposta su una domanda relativa alle differenze tra a varchar(255)e a varchar(256)per alcune ulteriori considerazioni
Max Vernon,

Grazie, avevo l'impressione che sarebbe stato qualcosa del genere e "usare solo ciò di cui hai bisogno" è solo una buona pratica di gestione delle risorse a tutto tondo. Tuttavia, alcuni dei dati dei nostri clienti fluttuano un po ', quindi generalmente facciamo le colonne un po' più larghe di quelle che devono essere, diciamo più grandi del 15-20%, per quelle colonne. Mi chiedevo se ci fossero altre considerazioni speciali; per esempio, qualcuno con cui lavoro mi ha detto di usare le dimensioni 2 ^ n - 1 (non ho trovato prove che sia una cosa però ...). Ma sembra che non ci sia altro che mantenere le cose il più piccolo possibile.
aristotle2600,

1
@ aristotle2600 Non sei sicuro di come applicare "2 ^ n - 1", ma vorrei chiedere ancora: è anche teoricamente possibile fare qualcosa di più grande di quello che ha bisogno di essere? Quella dimensione del 15-20% più grande non sarebbe la dimensione necessaria per non rompersi? ;-). Sono sicuro che sarebbe d'aiuto se tu fossi più esplicito nella fonte dei dati, perché a) se fai "URL" 1024 e qualcuno ha bisogno di 1060, allora dovrebbe essere 1060, ma b) se qualcuno vuole aggiungere 1000 caratteri per un campo di commento 500 char-limite, allora ancora solo bisogno di essere 500. Le persone possono entrare meno nei commenti, ma il prodotto SKU meglio essere abbastanza grande.
Solomon Rutzky,

@ aristotle2600 Ho appena aggiunto alcuni dei tuoi commenti qui alla domanda in quanto forniscono un buon contesto. Ho anche aggiunto delle cose alla fine della mia risposta :)
Solomon Rutzky il

Grazie mille per la tua risposta! Sì, i nomi e gli indirizzi fluttuano. Per quanto riguarda il paradosso sempre crescente del 20%, capisco cosa intendi, ma sto parlando della creazione della tabella iniziale. Un cliente ci dirà che inizierà a inviarci una nuova tabella e invierà dati di esempio (o solo il primo set di dati di produzione), che esamineremo e creeremo una tabella dalla nostra parte per conservare i dati. Vogliamo preparare il tavolo dalla nostra parte per gestire le importazioni future così come ciò che è nel campione. Ma alcune file sono destinate ad allungarsi, quindi le riempiamo. La domanda è: quanto ci sono e le linee guida tecniche?
aristotle2600,
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.