111 Stimmen

UUID-Leistung in MySQL?

Wir erwägen die Verwendung von UUID-Werten als Primärschlüssel für unsere MySQL-Datenbank. Die Daten, die eingefügt werden, werden von Dutzenden, Hunderten oder sogar Tausenden von entfernten Computern generiert und mit einer Rate von 100-40.000 Einfügungen pro Sekunde eingefügt, und wir werden nie irgendwelche Aktualisierungen vornehmen.

Die Datenbank selbst wird in der Regel etwa 50 Mio. Datensätze umfassen, bevor wir beginnen, die Daten zu bereinigen, also keine riesige Datenbank, aber auch keine winzige. Wir planen auch auf InnoDB zu laufen, obwohl wir offen sind, das zu ändern, wenn es eine bessere Engine für das, was wir tun, gibt.

Wir waren bereit, mit Java's Type 4 UUID zu arbeiten, aber beim Testen haben wir ein seltsames Verhalten festgestellt. Zum einen speichern wir als varchar(36) und ich erkenne jetzt, dass wir mit binary(16) besser dran wären - aber wie viel besser dran ist, weiß ich nicht.

Die wichtigere Frage ist: Wie stark beeinträchtigen diese Zufallsdaten den Index, wenn wir 50 Millionen Datensätze haben? Wären wir besser dran, wenn wir zum Beispiel eine UUID vom Typ 1 verwenden würden, bei der die äußersten linken Bits mit einem Zeitstempel versehen sind? Oder sollten wir die UUIDs vielleicht ganz weglassen und automatische Primärschlüssel in Betracht ziehen?

Ich bin auf der Suche nach allgemeinen Gedanken/Tipps zur Leistung verschiedener Arten von UUIDs, wenn sie als Index/Primärschlüssel in MySQL gespeichert werden. Vielen Dank!

3voto

theking2 Punkte 1467

Mir ist klar, dass diese Frage ziemlich alt ist, aber ich bin bei meinen Recherchen darauf gestoßen. Seitdem ist eine Reihe von Dingen passiert (SSD sind allgegenwärtig InnoDB bekam Updates usw.).

Bei meinen Nachforschungen fand ich folgendes interessant poste auf die Leistung:

und behauptet, dass aufgrund der Zufälligkeit eines GUID/UUID-Indexbaums kann ziemlich unausgewogen werden. In der MariaDB KB fand ich weiterer Beitrag eine Lösung vorgeschlagen. Aber seit dem neuen UUID_TO_BIN kümmert sich darum. Diese Funktion ist nur in MySQL (getestete Version 8.0.18) und nicht in MariaDB (Version 10.4.10) verfügbar

TL;DR: UUID als konvertierte/optimierte BINARY(16)-Werte speichern.

2voto

Nikolai Punkte 21

Ich würde jedem Server transaktionsbezogen eine numerische ID zuweisen. Dann wird jeder eingefügte Datensatz einfach seinen eigenen Zähler automatisch erhöhen. Die Kombination aus ServerID und RecordID wird eindeutig sein. Das Feld ServerID kann indiziert werden und die künftige Select-Leistung auf der Grundlage von ServerID (falls erforderlich) kann viel besser sein.

2voto

StephenS Punkte 1259

Die kurze Antwort ist, dass viele Datenbanken aufgrund eines Konflikts zwischen ihrer Indizierungsmethode und der gewollten Entropie der UUIDs in den höherwertigen Bits Leistungsprobleme haben (insbesondere bei hohem INSERT-Aufkommen). Es gibt mehrere gängige Hacks:

  • Wählen Sie einen anderen Indextyp (z.B. nonclustered bei MSSQL), dem es nichts ausmacht
  • die Daten munchen, um die Entropie in Bits niedrigerer Ordnung zu verlagern (z. B. Neuordnung der Bytes von V1 UUIDs bei MySQL)
  • die UUID zu einem Sekundärschlüssel mit einem automatisch inkrementierenden int-Primärschlüssel machen

... aber das sind alles Hacks - und wahrscheinlich noch dazu schwache.

Die beste Antwort, aber leider auch die langsamste, ist, von Ihrem Anbieter zu verlangen, dass er sein Produkt so verbessert, dass es mit UUIDs als Primärschlüssel wie mit jedem anderen Typ umgehen kann. Er sollte Sie nicht dazu zwingen, Ihren eigenen halbgaren Hack zu entwickeln, um sein Versäumnis auszugleichen, ein Problem zu lösen, das zu einem häufigen Anwendungsfall geworden ist und nur noch zunehmen wird.

1voto

MindStalker Punkte 14435

Wie wäre es mit einer handgefertigten UID? Geben Sie jedem der Tausenden von Servern eine ID und machen Sie den Primärschlüssel zu einem Kombischlüssel aus Autoinkrement, MachineID und MachineID.

1voto

Da der Primärschlüssel dezentral generiert wird, haben Sie ohnehin nicht die Möglichkeit, ein auto_increment zu verwenden.

Wenn Sie die Identität der entfernten Rechner nicht verbergen müssen, verwenden Sie UUIDs vom Typ 1 anstelle von UUIDs. Sie sind einfacher zu erzeugen und können zumindest die Leistung der Datenbank nicht beeinträchtigen.

Das Gleiche gilt für varchar (char, wirklich) vs. binary: es kann nur helfen. Ist es wirklich wichtig, wie viel Leistung verbessert wird?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X