Una domanda simile è stata posta prima
Implicazioni sulle prestazioni delle dimensioni MySQL VARCHAR
Ecco l'estratto della mia risposta
È necessario realizzare i compromessi dell'utilizzo di CHAR vs VARCHAR
Con i campi CHAR, ciò che assegni è esattamente quello che ottieni. Ad esempio, CHAR (15) alloca e memorizza 15 byte, indipendentemente dal carattere inserito nel campo. La manipolazione delle stringhe è semplice e diretta poiché la dimensione del campo dati è totalmente prevedibile.
Con i campi VARCHAR, ottieni una storia completamente diversa. Ad esempio VARCHAR (15) alloca effettivamente in modo dinamico fino a 16 byte, fino a 15 per i dati e, almeno, 1 byte aggiuntivo per memorizzare la lunghezza dei dati. Se hai la stringa 'ciao' da memorizzare che richiederà 6 byte, non 5. La manipolazione della stringa deve sempre eseguire una qualche forma di controllo della lunghezza in tutti i casi.
Il compromesso è più evidente quando si fanno due cose: 1. Memorizzare milioni o miliardi di righe 2. Indicizzare colonne che sono CHAR o VARCHAR
TRADEOFF # 1 Ovviamente, VARCHAR ha il vantaggio dato che i dati a lunghezza variabile produrrebbero file più piccole e, quindi, file fisici più piccoli.
TRADEOFF # 2 Poiché i campi CHAR richiedono una minore manipolazione delle stringhe a causa di larghezze di campo fisse, le ricerche dell'indice rispetto al campo CHAR sono in media il 20% più veloci di quelle dei campi VARCHAR. Questa non è alcuna congettura da parte mia. Il libro MySQL Database Design and Tuning ha eseguito qualcosa di meraviglioso su una tabella MyISAM per dimostrarlo. L'esempio nel libro ha fatto qualcosa di simile al seguente:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Questa direttiva forza tutti i VARCHAR a comportarsi come CHAR. L'ho fatto nel mio precedente lavoro nel 2007 e ho preso un tavolo da 300 GB e accelerato la ricerca dell'indice del 20%, senza cambiare nient'altro. Ha funzionato come pubblicato. Tuttavia, ha prodotto un tavolo di dimensioni quasi doppie, ma questo risale semplicemente al compromesso n. 1.
È possibile analizzare i dati archiviati per vedere cosa consiglia MySQL per la definizione di colonna. Basta eseguire quanto segue su qualsiasi tabella:
SELECT * FROM tblname PROCEDURE ANALYSE();
Ciò attraverserà l'intera tabella e raccomanderà le definizioni di colonna per ogni colonna in base ai dati in essa contenuti, ai valori minimi dei campi, ai valori massimi dei campi e così via. A volte, devi solo usare il buon senso con la pianificazione di CHAR vs VARCHAR. Ecco un buon esempio:
Se si memorizzano gli indirizzi IP, la maschera per tale colonna è al massimo di 15 caratteri (xxx.xxx.xxx.xxx). Vorrei saltare subito CHAR(15)
in un batter d'occhio perché la lunghezza degli indirizzi IP non varierà molto e la complessità aggiunta della manipolazione delle stringhe controllata da un byte aggiuntivo. Potresti ancora fare un PROCEDURE ANALYSE()
contro una colonna del genere. Potrebbe anche raccomandare VARCHAR. In questo caso, i miei soldi sarebbero ancora su CHAR su VARCHAR.
I problemi CHAR vs VARCHAR possono essere risolti solo attraverso un'adeguata pianificazione. Da un grande potere derivano grandi responsabilità (cliché ma vero).
AGGIORNARE
Quando si tratta di MD5, il calcolo di strlen
internamente dovrebbe essere eliminato quando si cambia l'intero formato di riga. Non sarebbe necessario modificare la definizione del campo.
Se la chiave MD5 è il solo VARCHAR presente, proverei a farlo e convertire il formato della riga della tabella in fisso . Se è presente un numero significativo di altri campi VARCHAR, anche loro ne trarrebbero beneficio. In cambio, la tabella si espanderebbe a circa il doppio della sua dimensione. Ma le query dovrebbero accelerare di circa il 20% in più senza ulteriore ottimizzazione.