Ich muss die Werte aller Felder eines Datensatzes mit einem bestimmten Schlüssel festlegen (der Schlüssel ist tatsächlich zusammengesetzt) und den Datensatz einfügen, wenn noch kein Datensatz mit einem solchen Schlüssel vorhanden ist.
REPLACE
scheint wie gedacht, um die Arbeit zu erledigen, aber gleichzeitig schlägt seine Handbuchseite vor
INSERT ... ON DUPLICATE KEY UPDATE
.
Welchen von ihnen sollte ich besser wählen und warum?
Der einzige "Nebeneffekt", der REPLACE
mir in den Sinn kommt, ist, dass dadurch die Autoinkrementierungswerte erhöht werden (zum Glück verwende ich keine), während dies INSERT ... ON DUPLICATE KEY UPDATE
wahrscheinlich nicht der Fall ist . Was sind die anderen praktischen Unterschiede zu beachten? In welchen besonderen Fällen kann REPLACE
man es vorziehen INSERT ... ON DUPLICATE KEY UPDATE
und umgekehrt?
Antworten:
REPLACE
führt intern ein Löschen und dann ein Einfügen durch. Dies kann zu Problemen führen, wenn eine Fremdschlüsseleinschränkung auf diese Zeile zeigt. In dieser Situation kannREPLACE
dies fehlschlagen oder schlimmer sein: Wenn Ihr Fremdschlüssel auf Kaskadenlöschung eingestellt ist,REPLACE
werden Zeilen aus anderen Tabellen gelöscht. Dies kann passieren, obwohl die Einschränkung sowohl vor als auch nach derREPLACE
Operation erfüllt wurde .Die Verwendung
INSERT ... ON DUPLICATE KEY UPDATE
vermeidet dieses Problem und wird daher bevorzugt.quelle
INSERT ... ON DUPLICATE KEY UPDATE
sieht es deutlich "besser" aus? In welchen Fällen kann "ERSETZEN" eine bessere Wahl sein?REPLACE
aktualisiert Ihren PK-Auto-Inkrement-Wert, wenn aDELETE
und ausgeführt werdenINSERT
. Welches ist genau das, was ich will. Ich möchte nicht, dass der Verbraucher den Datensatz unter derselben PK findet, damit er keine Zeilen erhält. Wenn ich möchte, dass sie es finden (aktuelles Update), benutze ichUPDATE
REPLACE
überINSERT ... ON DUPLICATE KEY UPDATE
? Warum sollte einINSERT
+DELETE
jemals einem vorgezogen werdenUPDATE
?Um die Frage nach der Leistung zu beantworten, habe ich einen Test mit beiden Methoden durchgeführt
Ersetzen In beinhaltet:
1.Try Einsatz auf dem Tisch
2. Wenn 1 ausfällt, Zeile löschen und einfügen neue Zeile
einfügen auf Duplizieren Key Update beinhaltet:
1.Try Einsatz auf dem Tisch
2.Falls 1 ausfällt, update Reihe
Würde man alle beteiligten Schritte sind Einsätze sollte es keinen Leistungsunterschied geben. Die Geschwindigkeit muss von der Anzahl der Aktualisierungen abhängen. Der schlimmste Fall ist, wenn alle Anweisungen aktualisiert werden
Ich habe beide Anweisungen in meiner InnoDB-Tabelle mit 62.510 Einträgen (nur Aktualisierungen) ausprobiert. Bei Camparing-Geschwindigkeiten:
Ersetzen in: 77,411 Sekunden
Einfügen bei doppelter Schlüsselaktualisierung: 2,446 Sekunden
Insert on Duplicate Key update is almost 32 times faster.
Tabellengröße: 1.249.250 Zeilen mit 12 Spalten auf einem Amazon m3.medium
quelle
Insert on Duplicate Key Replace
? War es langsamer?Bei Verwendung von
REPLACE
anstelle vonINSERT ... ON DUPLICATE KEY UPDATE
stelle ich manchmal Probleme mit der Schlüsselsperre oder dem Deadlock fest, wenn mehrere Abfragen für einen bestimmten Schlüssel schnell eingehen. Die Atomizität des letzteren (zusätzlich dazu, dass keine Kaskadenlöschungen verursacht werden) ist umso mehr ein Grund, es zu verwenden.quelle
Wenn Sie nicht alle Spalten auflisten,
REPLACE
werden alle nicht erwähnten Spalten mit ihren Standardwerten in den ersetzten Zeilen zurückgesetzt.ON DUPLICATE KEY UPDATE
lässt nicht erwähnte Spalten unverändert.quelle
Ich habe gerade herausgefunden, wie schwierig es ist, bei Tabellen mit einer FEDERATED-Speicher-Engine
INSERT...ON DUPLICATE KEY UPDATE
Anweisungen zu akzeptieren, die jedoch fehlschlagen (mit einem Fehler 1022: Kann nicht schreiben; Schlüssel in Tabelle duplizieren ...), wenn ein Schlüssel dupliziert wird Es tritt ein Verstoß auf - siehe den entsprechenden Aufzählungspunkt auf dieser Seite des MySQL-Referenzhandbuchs.Glücklicherweise konnte ich
REPLACE
anstelleINSERT...ON DUPLICATE KEY UPDATE
meines After-Insert-Triggers das gewünschte Ergebnis beim Replizieren von Änderungen in einer FEDERATED-Tabelle verwenden.quelle
Ersetzen scheint zwei Operationen auszuführen, falls der Schlüssel bereits vorhanden ist. Vielleicht impliziert das, dass es einen Geschwindigkeitsunterschied zwischen den beiden gibt?
(INSERT) ein Update gegen ein Delete + ein Insert (REPLACE)
EDIT: Meine Implikation, dass das Ersetzen langsamer sein könnte, ist eigentlich völlig falsch. Nun, laut diesem Blog-Beitrag sowieso ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks /.
quelle
"Es ist möglich, dass im Fall eines Duplikatschlüsselfehlers eine Speicher-Engine den REPLACE als Update und nicht als Delete plus Insert ausführt, aber die Semantik ist dieselbe."
http://dev.mysql.com/doc/refman/5.7/en/replace.html
quelle
REPLACE scheint manchmal notwendig zu sein, da INSERT IGNORE nicht mit Datentransformationen zu funktionieren scheint.
Wenn ich das mache, setze ich nur largeCityPop auf sich selbst:
In diesem Fall verwende ich die GROUP-Funktion nicht ordnungsgemäß:
Und wenn ich das mache, erkennt MySQL den Spaltennamen nicht:
Das funktioniert, scheint aber einfach hässlich:
quelle