Wir migrieren aus Leistungsgründen eine Datenbank von MySQL nach MongoDB und überlegen, was für IDs der MongoDB-Dokumente verwendet werden soll. Wir diskutieren zwischen der Verwendung von ObjectIDs, der MongoDB-Standardeinstellung, oder der Verwendung von UUIDs (die wir bisher in MySQL verwendet haben). Bisher müssen wir folgende Argumente unterstützen, um diese Optionen zu unterstützen:
ObjectIDs: ObjectIDs sind die MongoDB-Standardeinstellungen, und ich gehe davon aus (obwohl ich nicht sicher bin), dass dies einen Grund hat, was bedeutet, dass ich davon ausgehe, dass MongoDB sie effizienter handhaben kann als UUIDs oder einen anderen Grund hat, sie zu bevorzugen. Ich fand auch diese Stackoverflow-Antwort , in der erwähnt wird, dass die Verwendung von ObjectIDs die Indizierung effizienter macht. Es wäre jedoch schön, einige Metriken darüber zu haben, wie viel diese "effizientere" ist.
UUIDs: Unser grundlegendes Argument für die Verwendung von UUIDs (und es ist sehr wichtig) ist, dass sie auf die eine oder andere Weise von praktisch jeder Datenbank unterstützt werden. Dies bedeutet, dass wir uns für die Clients dieser API nicht ändern, wenn wir uns aus irgendeinem Grund dazu entschließen, von MongoDB zu etwas anderem zu wechseln, und dass wir bereits eine API haben, die Dokumente basierend auf ihren IDs aus der Datenbank abruft, da die IDs fortgesetzt werden können genau das gleiche sein. Wenn wir ObjectIDs verwenden würden, wäre ich mir nicht sicher, wie wir sie in eine andere Datenbank migrieren würden.
Hat jemand einen Einblick, ob eine dieser Optionen besser ist als die andere und warum? Haben Sie jemals UUIDs in MongoDB anstelle von ObjectIDs verwendet und wenn ja, auf welche Vorteile / Probleme sind Sie gestoßen?
Berücksichtigen Sie die Datenmenge, die Sie jeweils speichern würden.
Eine MongoDB- Objekt-ID ist 12 Byte groß, wird zur Speicherung gepackt und ihre Teile sind nach Leistung organisiert (dh der Zeitstempel wird zuerst gespeichert, was ein logisches Bestellkriterium ist).
Umgekehrt beträgt eine Standard-UUID 36 Byte, enthält Bindestriche und wird normalerweise als Zeichenfolge gespeichert. Selbst wenn Sie nicht numerische Zeichen entfernen und numerisch speichern möchten, müssen Sie sich dennoch mit dem "indexy" -Teil (der Teil einer UUID v1, der auf Zeitstempeln basiert) in der Mitte der UUID befinden und dies nicht tun. Es eignet sich gut zum Sortieren. Es wurden Studien durchgeführt, die eine performante UUID-Speicherung ermöglichen, und ich habe sogar eine Node.js-Bibliothek geschrieben , um die Verwaltung zu unterstützen.
Wenn Sie eine UUID verwenden möchten, sollten Sie sie für eine optimale Indizierung und Sortierung neu organisieren. Andernfalls stoßen Sie wahrscheinlich an eine Leistungswand.
quelle
0x04
. Sie haben Recht mit dem unglücklichen Zeitstempel, das ist ein echter Schmerz. Ich wünschte, es gäbe eine offizielle UUID-Version, die sich eher wie eine SQUUID verhält.Ich habe diese Benchmarks vor einiger Zeit gefunden, als ich die gleiche Frage hatte. Sie zeigen im Grunde, dass die Verwendung einer Guid anstelle von ObjectId zu einem Rückgang der Indexleistung führt.
Ich würde auf jeden Fall empfehlen, dass Sie die Benchmarks so anpassen, dass sie Ihr spezifisches reales Szenario imitieren und sehen, wie die Zahlen aussehen. Man kann sich nicht zu 100% auf generische Benchmarks verlassen.
quelle
Wir müssen darauf achten, die Kosten für das Einfügen einer Sache durch MongoDB von den Kosten für die Generierung der Sache zuzüglich dieser Kosten im Verhältnis zur Größe der Nutzlast zu unterscheiden. Unten finden Sie eine kleine Matrix, die die Methode zum Generieren der
_id
Kreuzung anhand der Größe einer optionalen zusätzlichen Nutzlast im Wert von Bytes zeigt. Bei den Tests wird nur Javascript verwendet, das auf dem MacBook Pro localhost für 100.000 Einfügungen unter VerwendunginsertMany
von Stapeln von 100 ohne Transaktionen durchgeführt wird, um zu versuchen, Netzwerk-, Chat- und andere Faktoren zu entfernen. Zwei Läufe mit Batch = 1 wurden ebenfalls durchgeführt, um den dramatischen Unterschied hervorzuheben.Method A : Simple int: _id:0, _id:1, ... B : ObjectId _id:ObjectId("5e0e6a804888946fa61a1976"), ... C : Simple string: _id:"A0", _id:"A1", ... D : UUID length string _id:"9575edcc-cb70-4d63-97ed-ee5d624de87b0", ... (but not actually generated by UUID() E : Real generated UUID _id: UUID("35992974-21ea-4f61-b715-2dfaed663b73"), ... (stored UUID() object) F : Real generated UUID _id: "6b16f733-ff24-4172-83f9-e4f96ace6775" (stored as string, e.g. UUID().toString().substr(6,36) Time in milliseconds to perform 100,000 inserts on fresh (empty) collection. Extra M E T H O D (Batch = 100) Payload A B C D E F % drop A to F -------- ---- ---- ---- ---- ---- ---- ------------ None 2379 2386 2418 2492 3472 4267 80% 512 2934 2928 3048 3128 4151 4870 66% 1024 3249 3309 3375 3390 4847 5237 61% 2048 3953 3832 3987 4342 5448 5888 49% 4096 6299 6343 6199 6449 7634 8640 37% 8192 9716 9292 9397 10816 11212 11321 16% Extra M E T H O D (Batch = 1) Payload A B C D E F % drop A to F -------- ----- ----- ----- ----- ----- ----- None 48006 48419 49136 48757 50649 51280 6.8% 1024 50986 50894 49383 49373 51200 51821 1.2%
Dies war ein schneller Test, aber es scheint klar zu sein, dass grundlegende Zeichenfolgen und Ints
_id
ungefähr die gleiche Geschwindigkeit haben, aber tatsächlich eine UUID generieren. Dies erhöht die Zeit - insbesondere, wenn Sie die Zeichenfolgenversion desUUID()
Objekts verwenden, z. B.UUID().toString().substr(6,36)
ist es auch erwähnenswert, dass das Erstellen einer ZeichenfolgeObjectId
angezeigt wird so schnell sein.quelle