2012-04-01 8 views
1

Ich habe eine große Tabelle von 10M Zeilen, nennen wir es Tabelle A. Ich habe auch eine andere Tabelle mit der gleichen Struktur genau und mit 2M Zeilen. Nennen wir es Tabelle B.Was ist der beste Weg, UPDATE mit INNER JOIN auf großen Tabellen in MySQL auszuführen?

Jede Zeile enthält ungefähr 20 Felder (sowohl textlich als auch numerisch).

Ich möchte alle Zeilen in Tabelle A mit Werten der entsprechenden Zeilen in Tabelle B (durch den Primärschlüssel verbunden) aktualisieren.

Trivial UPDATE läuft mehrere Stunden:

UPDATE A 
INNER JOIN B 
    ON A.primary_key=B.primary_key 
SET A.field1=B.field1, 
    A.field2=B.field2....; 

Können Sie etwas smarter Ansatz beraten eher dann einen einzigen Befehl UPDATE auf INNER JOIN?

Vielen Dank im Voraus!

+0

innodb oder myisam? wenn innodb trans beginnt; aktualisieren; verpflichten; http://dev.mysql.com/doc/refman/5.0/en/commit.html –

+0

InnoDB. Warum "start trans; update; commit" das UPDATE schneller macht? – diemacht

Antwort

0

Es klingt, als ob Sie aufgrund der Größe des resultierenden Datasets wahrscheinlich Pufferprobleme haben. Sie könnten versuchen, es in kleineren Brocken zu machen, vielleicht 100K Reihen gleichzeitig. Sie könnten es basierend auf dem PK tun. Suchen Sie den maximalen Primärschlüssel in Tabelle A und teilen Sie ihn dann durch 100.000, um die Anzahl der erforderlichen Iterationen zu erhalten.

// PSEUDO CODE 
MAX = SELECT MAX(primary_key) FROM table A 
NUM_PER_QUERY = 100000 
NUM_ITERATIONS = CEIL(MAX/NUM_PER_QUERY) 

for (i = 0; i < NUM_ITERATIONS; i++) { 
    UPDATE .... WHERE A.primary_key BETWEEN ((i * NUM_PER_QUERY) + 1) AND ((i + 1) * NUM_PER_QUERY) 
} 
+0

Das Problem bei diesem Ansatz besteht darin, dass davon ausgegangen wird, dass die Primärschlüssel gleichmäßig verteilt sind. In meinem Fall kann diese Annahme jedoch nicht gemacht werden. – diemacht

+0

Es spielt keine Rolle, was die Schlüsselverteilung ist. Dies bedeutet, dass jede Abfrage maximal 100 K Zeilen umfasst, was deutlich weniger Arbeitsspeicher benötigt, als wenn versucht wird, die Aktualisierung auf einmal durchzuführen. – nnichols