In che modo le colonne varchar vengono gestite internamente da un motore di database? Per una colonna definita come char (100), il DBMS alloca 100 byte contigui sul disco. Tuttavia, per una colonna definita come varchar (100), presumibilmente non è il caso, dal momento che l'intero punto di varchar non è di allocare più spazio di quanto richiesto per memorizzare il valore di dati effettivo memorizzato nella colonna. Quindi, quando un utente aggiorna una riga di database contenente una colonna vuota varchar (100) ad un valore costituito da 80 caratteri, ad esempio, da dove viene assegnato lo spazio per gli 80 caratteri? Sembra che le colonne varchar debbano comportare una discreta quantità di frammentazione delle righe effettive del database, almeno negli scenari in cui i valori delle colonne vengono inizialmente inseriti come vuoti o NULL e quindi aggiornati successivamente con valori effettivi. Questa frammentazione si traduce in prestazioni degradate sulle query di database, anziché utilizzare valori di tipo char, in cui lo spazio per le colonne archiviate nelle righe viene allocato in modo contiguo? Ovviamente l'utilizzo dei risultati varchar comporta meno spazio su disco rispetto all'utilizzo di char, ma si verifica un calo delle prestazioni durante l'ottimizzazione delle prestazioni delle query, in particolare per le colonne i cui valori vengono frequentemente aggiornati dopo l'inserimento iniziale?Il risultato di varchar in termini di prestazioni è dovuto alla frammentazione dei dati?
risposta
Le strutture di dati utilizzate all'interno di un motore di database sono molto più complesse di te Sì, ci sono problemi di frammentazione e problemi in cui l'aggiornamento di un varchar con un valore elevato può causare un calo di prestazioni, tuttavia è difficile spiegare/comprendere quali sono le implicazioni di tali problemi senza una piena comprensione delle strutture dati coinvolto.
Per MS SQL server si potrebbe desiderare di iniziare con la comprensione pagine - l'unità fondamentale di stoccaggio (vedi http://msdn.microsoft.com/en-us/library/ms190969.aspx)
In termini di implicazioni sulle prestazioni di correzioni vs tipi di archiviazione variabile sulle prestazioni ci sono un certo numero di punti di prendere in considerazione:
- Utilizzando colonne di lunghezza variabile in grado di migliorare le prestazioni in quanto consente più righe per adattarsi in una singola pagina, il che significa meno legge
- Utilizzando colonne di lunghezza variabile richiede particolare valori di offset, e la manutenzione di questi valori richiede s un leggero overhead, tuttavia questo overhead extra è generalmente trascurabile.
- Un altro costo potenziale è il costo di aumentare le dimensioni di una colonna quando la pagina contenente la riga è quasi pieno
Come si può vedere, la situazione è piuttosto complessa - in generale però si può fidare della banca dati il motore è abbastanza bravo a gestire i tipi di dati variabili e dovrebbe essere il tipo di dati da scegliere quando potrebbe esserci una varianza significativa della lunghezza dei dati contenuti in una colonna.
A questo punto ho anche intenzione di raccomandare l'eccellente libro "Microsoft Sql Server 2008 Internals" per ulteriori informazioni su come le cose complesse come questa si ottengono davvero!
Nella tua domanda fai molte assunzioni che non sono necessariamente vere.
Il tipo di una colonna in qualsiasi DBMS non indica nulla sulla natura della memorizzazione di tali dati a meno che la documentazione non indichi chiaramente come vengono memorizzati i dati. Se questo non è indicato, non si sa come è memorizzato e il DBMS è libero di cambiare il meccanismo di archiviazione dal rilascio al rilascio.
Infatti alcuni database memorizzano internamente i campi CHAR come VARCHAR, mentre altri decidono su come archiviare la colonna in base alla dimensione dichiarata della colonna. Alcuni database archiviano VARCHAR con le altre colonne, alcuni con dati BLOB e altri implementano altri archivi. Alcuni database riscrivono sempre l'intera riga quando una colonna viene aggiornata, altri no. Alcuni pad VARCHAR consentono un aggiornamento futuro limitato senza spostare lo spazio di archiviazione.
Il DBMS è responsabile di capire come archiviare i dati e restituirli a voi in modo rapido e coerente. Mi stupisce sempre quante persone provano a pensare al database, generalmente prima di rilevare qualsiasi problema di prestazioni.
La risposta dipenderà dal DBMS specifico. Per Oracle, è certamente possibile finire con la frammentazione sotto forma di "file concatenate" e ciò comporta una penalizzazione delle prestazioni. Tuttavia, è possibile mitigare ciò predistribuendo un po 'di spazio vuoto nei blocchi di tabella per consentire l'espansione dovuta agli aggiornamenti. Tuttavia, le colonne CHAR in genere rendono la tabella molto più grande, il che ha un suo impatto sulle prestazioni. CHAR ha anche altri problemi, come i confronti vuoti, il che significa che, in Oracle, l'uso del tipo di dati CHAR è quasi mai una buona idea.
La tua domanda è troppo generica perché diversi motori di database avranno un comportamento diverso. Se hai davvero bisogno di sapere questo, ti suggerisco di impostare un benchmark per scrivere un gran numero di record e cronometrare. Vorresti avere un numero di record sufficiente per scrivere almeno un'ora.
Come hai suggerito, sarebbe interessante vedere cosa succede se scrivi di inserire tutti i record con una stringa vuota ("") e poi aggiornali per avere 100 caratteri che sono ragionevolmente casuali, non solo 100 Xs.
Se si prova questo con SQLITE e non si riscontra alcuna differenza significativa, penso che sia improbabile che i server di database più grandi, con tutte le analisi e le ottimizzazioni in corso, siano peggio di SQLITE.
SQLite è un perfetto esempio di ciò che stavo dicendo nel mio commento, sopra, sul non conoscere il meccanismo di archiviazione per i dati. Sotto il cofano, SQLite non ha nemmeno la memoria dattiloscritta - è possibile inserire dati simili a VARCHAR in qualsiasi tipo di colonna (anche INTEGER). –
La domanda è: questo fa alcuna differenza per le prestazioni? Solo un test lo dirà di sicuro. Per prima cosa, gli sviluppatori di software potrebbero aver realizzato il potenziale di frammentazione e attenuarlo in qualche modo. Per un altro, il riempimento extra di caratteri a lunghezza fissa probabilmente causerà più I/O di file, ma anche questo può essere mitigato. È necessario confrontare le varianti per sapere se c'è una differenza significativa. –
In SQL Server varchar (tranne varchar (MAX)) viene generalmente archiviato insieme al resto dei dati della riga (nella stessa pagina se i dati della riga sono < 8KB e nella stessa misura se è < 64 KB. i grandi tipi di dati come TEXT, NTEXT, IMAGE, VARHCAR (MAX), NVARHCAR (MAX), XML e VARBINARY (MAX) vengono memorizzati separatamente
Questo sarà completamente specifico del database.
So che in Oracle il database riserva una determinata percentuale di ogni blocco per gli aggiornamenti futuri (il parametro PCTFREE). Ad esempio, se PCTFREE è impostato su 25%, un blocco verrà utilizzato solo per i nuovi dati finché non sarà pieno al 75%. Facendo ciò, si lascia spazio per le file a crescere. Se la fila cresce in modo tale che lo spazio riservato del 25% è completamente esaurito, si finisce con le righe concatenate e una penalità legata alle prestazioni. Se si scopre che una tabella ha un numero elevato di righe concatenate, è possibile ottimizzare PCTFREE per quella tabella. Se hai una tabella che non avrà mai alcun aggiornamento, un PCTFREE pari a zero avrebbe senso
- 1. È varchar (128) migliore di varchar (100)
- 2. In termini di prestazioni, che è meglio Flex o Silverlight?
- 3. Il funzionamento di varchar è migliore della stringa in Hive?
- 4. Quali sarebbero i pro ei contro dei dati gerarchici rispetto ai dati correlati, in termini di prestazioni (e categorizzazione)?
- 5. apache solr: somma dei dati il risultato di gruppo da
- 6. R prestazioni con risagomatura dei dati
- 7. Atomic Integer lazySet guadagni in termini di prestazioni
- 8. Strutture dati probabilistiche efficienti in termini di spazio per il recupero dei numeri
- 9. Modifica dello stile di codifica dovuto alle prestazioni del GC di Android, quanto è lontano?
- 10. indicizzazione delle prestazioni BigInt vs VarChar
- 11. È possibile risolvere il problema di frammentazione della memoria CUDA?
- 12. Frammentazione del pacchetto durante l'invio di dati via SSLStream
- 13. Perché il modo System.nanoTime() è più lento (in termini di prestazioni) rispetto a System.currentTimeMillis()?
- 14. L'espressione regolare Java offre vantaggi in termini di prestazioni?
- 15. Esiste un vantaggio in termini di prestazioni quando si specifica esplicitamente il binding OneWay durante l'impostazione dei binding in WPF?
- 16. se condizione vs &&, c'è qualche guadagno in termini di prestazioni
- 17. che è meglio in termini di prestazioni di analisi in Android, XML o JSON?
- 18. Come si confrontano le funzioni Python in termini di prestazioni?
- 19. C'è un guadagno in termini di prestazioni dal caching $ (questo)?
- 20. Affettare eccezioni - è dovuto al costruttore di copie generato?
- 21. Istruzione rispetto alla dichiarazione preparata in termini di precompilazione
- 22. Postgres: Converti varchar in testo
- 23. Qual è il limite per stimolare lo streaming in termini di quantità di dati?
- 24. Prestazioni MySQL di campo varchar unico vs bigint unico
- 25. Qual è il significato dei termini "Flusso normale" e "Fuori flusso", in termini di HTML, CSS e Browser?
- 26. AtomicXXX.lazySet (...) in termini di accadimenti prima dei bordi
- 27. È possibile ottenere vantaggi in termini di prestazioni utilizzando VIEW anziché JOINs?
- 28. Esiste un vantaggio in termini di prestazioni nell'utilizzo di elenchi di lunghezza fissa in Dart?
- 29. Conversione dei tipi di dati in IBM DB2: BIGINT in VARCHAR
- 30. mySQL convertire varchar alla data
+1: la domanda presuppone anche una quantità significativa di aggiornamento che espande i campi VARCHAR. Anche questo può essere - in alcune applicazioni - una percentuale di righe estremamente piccola. –
Grazie per le risposte. La mia domanda di base era come il DBMS memorizza dati di lunghezza variabile, e le risposte me ne hanno fatto luce. Il DB in questione ha un numero di colonne piuttosto grandi che sono inizialmente vuote nell'inserimento e compilate in seguito, quindi la mia preoccupazione generale era come questo viene gestito dal DBMS, e possibili problemi di prestazioni dovuti al salto intorno al disco rispetto all'utilizzo di caratteri. –
@E. Dipende interamente dal tuo DBMS ed è possibile che non pubblichino tali informazioni. Tuttavia, i più moderni DBMS sono a conoscenza di problemi come la frammentazione dei dati e includono ottimizzazioni per evitare la perdita di prestazioni. A meno che non rilevi un problema di prestazioni, lascerei che fosse il database a gestirlo per te.(A occhio e croce, immagino che la maggior parte dei DBMS scriverà la riga sulla memoria corrente se si adatta, o in una nuova memoria, se non lo fa, liberando la vecchia memoria, con più o meno le stesse prestazioni in entrambi Astuccio). –