Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL binario contro non binario per gli ID hash

Sì. Spesso un digest hash viene memorizzato come rappresentazione ASCII di cifre esadecimali, ad esempio MD5 della parola 'hash' è:

0800fc577294c34e0b28ad2839435945

Questa è una stringa ASCII di 32 caratteri.

Ma MD5 produce davvero un valore hash binario a 128 bit. Questo dovrebbe richiedono solo 16 byte da archiviare come valori binari anziché cifre esadecimali. Quindi puoi guadagnare un po' di efficienza nello spazio usando stringhe binarie.

CREATE TABLE test.foobar (
  id BINARY(16) NOT NULL PRIMARY KEY
);

INSERT INTO test.foobar (id) VALUES (UNHEX(MD5('hash')));

Rif. i tuoi commenti sul fatto che sei più preoccupato per le prestazioni che per l'efficienza dello spazio:

Non conosco alcun motivo per cui il tipo di dati BINARY sarebbe più veloce di CHAR.

Essere grandi la metà può essere un vantaggio per le prestazioni se si utilizzano i buffer della cache in modo efficace. Cioè, una determinata quantità di memoria cache può memorizzare il doppio delle righe di dati BINARY se la stringa è la metà della dimensione del CHAR necessario per memorizzare lo stesso valore in formato esadecimale. Allo stesso modo, la memoria cache per l'indice su quella colonna può archiviare il doppio.

Il risultato è una cache più efficace, perché una query casuale ha maggiori possibilità di raggiungere i dati o l'indice memorizzati nella cache, invece di richiedere l'accesso al disco. L'efficienza della cache è importante per la maggior parte delle applicazioni di database, perché in genere il collo di bottiglia è l'I/O del disco. Se puoi utilizzare la memoria cache per ridurre la frequenza dell'I/O del disco, il rapporto qualità-prezzo è molto maggiore rispetto alla scelta tra un tipo di dati o l'altro.

Per quanto riguarda la differenza tra una stringa hash memorizzata in BINARY e un BIGINT, sceglierei BIGINT. L'efficienza della cache sarà ancora maggiore e anche su processori a 64 bit l'aritmetica e il confronto degli interi dovrebbero essere molto veloci.

Non ho misurazioni per supportare le affermazioni di cui sopra. Il vantaggio netto della scelta di un tipo di dati rispetto a un altro dipende molto dai modelli di dati e dai tipi di query nel database e nell'applicazione. Per ottenere la risposta più precisa, devi provare entrambe le soluzioni e misurare la differenza.

Rif. la tua supposizione che il confronto di stringhe binarie sia più veloce del confronto predefinito di stringhe senza distinzione tra maiuscole e minuscole, ho provato il seguente test:

mysql> SELECT BENCHMARK(100000000, 'foo' = 'FOO');
1 row in set (5.13 sec)

mysql> SELECT BENCHMARK(100000000, 'foo' = BINARY 'FOO');
1 row in set (4.23 sec)

Il confronto tra stringhe binarie è quindi più veloce del 17,5% rispetto al confronto tra stringhe senza distinzione tra maiuscole e minuscole. Ma nota che dopo aver valutato questa espressione 100 milioni di volte, la differenza totale è ancora inferiore a 1 secondo. Mentre possiamo misurare la differenza relativa di velocità, la differenza assoluta di velocità è davvero insignificante.

Quindi ribadisco:

  • Misura, non indovinare o supporre. Le tue ipotesi plausibili saranno sbagliate per la maggior parte del tempo. Misura prima e dopo ogni modifica che apporti, così sai quanto ha aiutato.
  • Investi tempo e attenzione dove ottieni il miglior rapporto qualità-prezzo.
  • Non preoccuparti per le piccole cose. Ovviamente, una piccola differenza si somma con un numero sufficiente di iterazioni, ma date queste iterazioni, è comunque preferibile un miglioramento delle prestazioni con un vantaggio assoluto maggiore.