Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Binär gegen Nicht-Binär für Hash-IDs

Ja. Häufig wird ein Hash-Digest als ASCII-Darstellung von Hexadezimalziffern gespeichert, zum Beispiel ist MD5 des Wortes „Hash“:

0800fc577294c34e0b28ad2839435945

Dies ist eine 32-stellige ASCII-Zeichenfolge.

Aber MD5 erzeugt wirklich einen 128-Bit-Binär-Hash-Wert. Das sollte erfordern nur 16 Bytes, die als Binärwerte anstelle von Hex-Ziffern gespeichert werden müssen. Sie können also etwas Platz sparen, indem Sie binäre Strings verwenden.

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

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

Betreff. Ihre Kommentare, dass Sie sich mehr Sorgen um die Leistung als um die Platzeffizienz machen:

Ich kenne keinen Grund, warum der BINARY-Datentyp schneller als CHAR wäre.

Halb so groß zu sein, kann für die Leistung von Vorteil sein, wenn Sie Cache-Puffer effektiv nutzen. Das heißt, eine bestimmte Menge an Cache-Speicher kann doppelt so viele Zeilen im Wert von BINARY-Daten speichern, wenn die Zeichenfolge halb so groß ist wie das CHAR, das zum Speichern desselben Werts in Hex benötigt wird. Ebenso kann der Cache-Speicher für den Index dieser Spalte doppelt so viel speichern.

Das Ergebnis ist ein effektiverer Cache, da eine zufällige Abfrage eine größere Chance hat, auf die zwischengespeicherten Daten oder den Index zu treffen, anstatt einen Festplattenzugriff zu erfordern. Die Cache-Effizienz ist für die meisten Datenbankanwendungen wichtig, da der Engpass normalerweise die Festplatten-E/A ist. Wenn Sie den Cache-Speicher verwenden können, um die Häufigkeit der Platten-I/O zu reduzieren, ist dies ein viel größeres Preis-Leistungs-Verhältnis als die Wahl zwischen dem einen oder anderen Datentyp.

Was den Unterschied zwischen einem in BINARY gespeicherten Hash-String und einem BIGINT betrifft, würde ich BIGINT wählen. Die Cache-Effizienz wird noch größer, und auch auf 64-Bit-Prozessoren sollten Integer-Arithmetik und -Vergleiche sehr schnell sein.

Ich habe keine Messungen, um die obigen Behauptungen zu stützen. Der Nettovorteil der Auswahl eines Datentyps gegenüber einem anderen hängt stark von Datenmustern und Abfragetypen in Ihrer Datenbank und Anwendung ab. Um die genaueste Antwort zu erhalten, müssen Sie beide Lösungen ausprobieren und den Unterschied messen.

Betreff. Ihre Vermutung, dass der binäre String-Vergleich schneller ist als der Standard-String-Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung, habe ich mit dem folgenden Test versucht:

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)

Der binäre String-Vergleich ist also 17,5 % schneller als der String-Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung. Beachten Sie jedoch, dass nach 100 Millionen Auswertungen dieses Ausdrucks die Gesamtdifferenz immer noch weniger als 1 Sekunde beträgt. Während wir den relativen Geschwindigkeitsunterschied messen können, ist der absolute Geschwindigkeitsunterschied wirklich unbedeutend.

Also wiederhole ich:

  • Messen, nicht raten oder vermuten. Ihre fundierten Vermutungen werden die meiste Zeit falsch sein. Messen Sie vor und nach jeder Änderung, die Sie vornehmen, damit Sie wissen, wie sehr sie geholfen hat.
  • Investieren Sie Ihre Zeit und Aufmerksamkeit dort, wo Sie das Beste für Ihr Geld bekommen.
  • Schwitzen Sie nicht die kleinen Sachen. Natürlich summiert sich ein winziger Unterschied mit genügend Iterationen, aber angesichts dieser Iterationen ist eine Leistungsverbesserung mit größerem absoluten Nutzen immer noch vorzuziehen.