Ich schreibe eine Anwendung, die über einen längeren Zeitraum eine große Anzahl von Aktualisierungen in der Datenbank löschen muss, und ich bin nicht sicher, wie die Abfrage optimiert werden kann. Derzeit verwende ich INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE
, mit dem alle Werte in einer Abfrage zusammengefasst werden, die jedoch in großen Tabellen äußerst langsam ausgeführt wird. Ich muss eigentlich nie Zeilen einfügen.
Andere Ansätze, die ich gesehen habe, sind das Aktualisieren mit SET value = CASE WHEN...
(was aufgrund der Art und Weise, wie ich die Abfragen erstelle, und ich bin mir nicht sicher, wie die Leistung von CASE
Hunderten / Tausenden von Schlüsseln ist) und einfach das mehrfache Verketten Aktualisierung. Wäre beides schneller als meine derzeitige Methode?
Es verwirrt mich, dass es, soweit ich das beurteilen kann, in MySQL keinen idiomatischen und effizienten Weg gibt, dies zu tun. Wenn es wirklich keinen Weg gibt, der schneller ist als ON DUPLICATE KEY
, würde es sich lohnen, zu PostgreSQL zu wechseln und dessen UPDATE FROM
Syntax zu verwenden?
Alle anderen Vorschläge werden auch sehr geschätzt!
Bearbeiten: Hier ist eine der Tabellen, die häufig aktualisiert wird. Ich habe Spaltennamen entfernt, weil sie irrelevant sind.
CREATE TABLE IF NOT EXISTS `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` bigint(20) unsigned NOT NULL DEFAULT '0',
`b` bigint(20) unsigned NOT NULL DEFAULT '0',
`c` enum('0','1','2') NOT NULL DEFAULT '0',
`d` char(32) NOT NULL,
-- trimmed --
PRIMARY KEY (`id`),
KEY `a` (`a`),
KEY `b` (`b`),
KEY `c` (`c`),
KEY `d` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Antworten:
Da Sie
InnoDB
Tabellen verwenden, besteht die naheliegendste Optimierung darin, mehrereUPDATE
s in einer Transaktion zu gruppieren .Als
InnoDB
Transaktionsmodul zahlen Sie nicht nur für sichUPDATE
selbst, sondern auch für den gesamten Transaktionsaufwand: Verwalten des Transaktionspuffers, des Transaktionsprotokolls und Löschen des Protokolls auf die Festplatte.Wenn Sie mit der Idee logisch vertraut sind, versuchen Sie
UPDATE
, jeweils 100-1000 Sekunden zu gruppieren , jedes Mal wie folgt verpackt:Mögliche Nachteile:
UPDATE
Sekunden angesammelt haben. Daher möchten Sie möglicherweise auch eine Zeitüberschreitung habenquelle