Warum die Verwendung von UUID als Primärschlüssel in MySQL die Leistung beeinträchtigen kann
Grace Collins
Solutions Engineer · Leapcell

Die Verwendung einer UUID als Primärschlüssel in großen Tabellen kann zu Leistungsproblemen führen, insbesondere in Bezug auf die Effizienz beim Einfügen und Ändern von Daten. Im Folgenden finden Sie eine detaillierte Analyse der Gründe dafür, einschließlich der Frage, warum das Ändern von Daten Indexaktualisierungen verursacht und warum zeichenbasierte Primärschlüssel weniger effizient sind.
Probleme bei der Verwendung von UUID als Primärschlüssel
Eigenschaften von UUID
- Eine UUID ist eine 128-Bit-Zeichenkette, die typischerweise als 36 Zeichen dargestellt wird (z. B.
550e8400-e29b-41d4-a716-446655440000
). - UUIDs sind global eindeutig und eignen sich daher zur Erzeugung eindeutiger Kennungen in verteilten Systemen.
Nachteile der Verwendung von UUID als Primärschlüssel
-
Geringe Indexeffizienz
- Indexgröße: Eine UUID ist ein String-Typ und belegt viel Speicherplatz (36 Byte), während ein Integer-Primärschlüssel (z. B.
BIGINT
) nur 8 Byte belegt. Je größer der Index, desto geringer die Effizienz von Speicherung und Abfragen. - Indexaufteilung: UUIDs sind unsortiert, was bedeutet, dass beim Einfügen neuer Daten häufige Aufteilungen und Neuausrichtungen des Indexbaums auftreten können, was die Leistung beeinträchtigt.
- Indexgröße: Eine UUID ist ein String-Typ und belegt viel Speicherplatz (36 Byte), während ein Integer-Primärschlüssel (z. B.
-
Schlechte Einfügeleistung
- Zufälligkeit: Da UUIDs unsortiert sind, kann jeder neue Datensatz an einer beliebigen Position im Indexbaum eingefügt werden, was zu häufigen Anpassungen des Indexbaums führt.
- Seitenaufteilung: Die InnoDB-Speicher-Engine verwendet einen B+-Baum als Indexstruktur. Zufällige Einfügungen können zu Seitenaufteilungen führen und die Anzahl der Festplatten-I/O-Operationen erhöhen.
-
Schlechte Abfrageleistung
- Geringe Vergleichseffizienz: String-Vergleiche sind langsamer als Integer-Vergleiche, insbesondere in großen Tabellen, wo die Abfrageleistung deutlich abnimmt.
- Großer Index-Scanbereich: Da UUID-Indizes mehr Speicherplatz belegen, erhöht sich der Scanbereich der Indizes, was die Abfrageeffizienz reduziert.
Warum das Ändern von Daten Indexaktualisierungen verursacht
Zweck von Indizes
- Indizes sind Datenstrukturen (wie z. B. B+-Bäume), die erstellt werden, um Abfragen zu beschleunigen.
- Wenn Daten geändert werden, muss auch der Index aktualisiert werden, um die Datenkonsistenz zu gewährleisten.
Auswirkungen der Datenänderung auf Indizes
-
Aktualisieren des Primärschlüssels
- Wenn der Primärschlüsselwert geändert wird, muss MySQL den alten Primärschlüsselindexeintrag löschen und einen neuen Primärschlüsselindexeintrag einfügen.
- Dieser Prozess erfordert Anpassungen am Indexbaum, wodurch die Anzahl der Festplatten-I/O-Operationen erhöht wird.
-
Aktualisieren von Nicht-Primärschlüsselspalten
- Wenn die geänderte Spalte eine indizierte Spalte ist (z. B. ein eindeutiger Index oder ein regulärer Index), muss MySQL die entsprechenden Indexeinträge aktualisieren.
- Dieser Prozess verursacht ebenfalls Anpassungen des Indexbaums.
Zusätzlicher Overhead von UUID-Primärschlüsseln
- Da UUIDs unsortiert sind, kann das Ändern des Primärschlüsselwerts dazu führen, dass der neue Wert an einer anderen Position im Indexbaum eingefügt wird, was zu häufigen Anpassungen des Indexbaums führt.
- Im Vergleich zu sortierten Primärschlüsseln (wie z. B. automatisch inkrementierenden IDs) verursacht das Ändern eines UUID-Primärschlüssels höhere Kosten.
Warum zeichenbasierte Primärschlüssel die Effizienz reduzieren
Großer Speicherplatzbedarf
- Zeichenbasierte Primärschlüssel (wie z. B. UUIDs) benötigen mehr Speicherplatz als Integer-Primärschlüssel.
- Die Größe eines Indexes wirkt sich direkt auf die Abfrageleistung aus – je größer der Index, desto mehr Festplatten-I/O-Operationen sind bei Abfragen erforderlich.
Geringe Vergleichseffizienz
- String-Vergleiche sind langsamer als Integer-Vergleiche, insbesondere in großen Tabellen, wo die Abfrageleistung deutlich abnimmt.
- Zum Beispiel ist
WHERE id = '550e8400-e29b-41d4-a716-446655440000'
weniger effizient alsWHERE id = 12345
.
Indexaufteilung
- Zeichenbasierte Primärschlüssel sind oft unsortiert, was bedeutet, dass beim Einfügen neuer Daten häufige Indexbaumaufteilungen und Neuausrichtungen auftreten können, was die Leistung beeinträchtigt.
Wie man die Leistung von UUID-Primärschlüsseln optimiert
Verwenden Sie sortierte UUIDs
- Verwenden Sie sortierte UUIDs (wie UUIDv7), um Indexaufteilungen und Seitenaufteilungen zu reduzieren.
- Sortierte UUIDs können basierend auf Zeitstempeln generiert werden, um die Einfügereihenfolge sicherzustellen.
Speichern Sie UUIDs im Binärformat
- Speichern Sie UUIDs als
BINARY(16)
anstelle vonCHAR(36)
, um Speicherplatz zu sparen.
CREATE TABLE users ( id BINARY(16) PRIMARY KEY, name VARCHAR(255) );
Verwenden Sie automatisch inkrementierende Primärschlüssel + UUID
- Verwenden Sie einen automatisch inkrementierenden Primärschlüssel als physischen Primärschlüssel und eine UUID als logischen Primärschlüssel.
CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, uuid CHAR(36) UNIQUE, name VARCHAR(255) );
Verwenden Sie partitionierte Tabellen
- Partitionieren Sie große Tabellen, um die Größe einzelner Indexbäume zu reduzieren und die Abfrageleistung zu verbessern.
Zusammenfassung
-
Nachteile der Verwendung von UUID als Primärschlüssel
- Geringe Indexeffizienz, schlechte Einfüge- und Abfrageleistung.
- Häufige Indexaktualisierungen beim Ändern von Daten, was zu Leistungseinbußen führt.
-
Gründe für die geringe Effizienz zeichenbasierter Primärschlüssel
- Großer Speicherplatzbedarf, geringe Vergleichseffizienz und häufige Indexaufteilungen.
-
Optimierungsempfehlungen
- Verwenden Sie sortierte UUIDs oder speichern Sie sie im Binärformat.
- Kombinieren Sie automatisch inkrementierende Primärschlüssel mit UUIDs.
- Partitionieren Sie große Tabellen.
Wir sind Leapcell, Ihre erste Wahl für das Hosting von Backend-Projekten.
Leapcell ist die Serverless-Plattform der nächsten Generation für Webhosting, asynchrone Aufgaben und Redis:
Multi-Sprachen-Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Mio. Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeit-Metriken und -Protokollierung für verwertbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Automatische Skalierung zur einfachen Bewältigung hoher Parallelität.
- Kein operativer Aufwand – konzentrieren Sie sich einfach auf den Aufbau.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ