2009-05-10 2 views
0

Ich habe Batch-Prozess, wenn ich meine Db-Tabelle, um 100000-500000 Zeilen, von hochgeladenen CVS-Datei aktualisieren muss. Normalerweise dauert es 20-30 Minuten, manchmal länger.Wie lange Batch-Prozesse in PHP zu tun?

Was ist der beste Weg? irgendwelche guten Praktiken dazu? Jeder Vorschlag würde geschätzt werden

Danke.

+0

Hm, beim Lesen fragen Sie noch einmal - verwenden Sie eigentlich * MySQL überhaupt? – Tomalak

Antwort

1

Wenn Sie eine Menge Einfügungen machen, machen Sie Masseneinlagen? das heißt wie folgt aus:

INSERT INTO table (col1 col2) VALUES (val1a, val2a), (val1b, val2b), (.... 

die dramatisch Einsätze beschleunigt.

Eine andere Sache, die Sie tun können, ist die Indizierung zu deaktivieren, während Sie die Änderungen vornehmen, und dann lassen Sie die Indizes in einem Rutsch neu erstellen, wenn Sie fertig sind.

Ein bisschen mehr Detail über das, was du tust und du vielleicht mehr Ideen

1

Die PEAR hat ein Paket Benchmark hat eine Benchmark_Profiler Klasse aufgerufen, die Sie den langsamsten Abschnitt des Codes helfen können, finden Sie so optimieren können .

1

Wir hatten eine solche Funktion in einer großen Anwendung. Wir hatten das Problem, Millionen von Zeilen aus einem CSV in eine Tabelle mit 9 Indizes einzufügen. Nach vielen Refactoring fanden wir den idealen Weg, die Daten einzufügen, war es in eine [temporäre] Tabelle mit dem mysql LOAD DATA INFILE Befehl zu laden, die Transformationen dort durchzuführen und das Ergebnis mit mehreren Insert-Abfragen in die eigentliche Tabelle (INSERT INTO ... SELECT FROM) nur zu kopieren 50k Zeilen oder so mit jeder Abfrage (die besser als die Ausgabe einer einzigen Einfügung, aber YMMV ausgeführt).

+0

Verdammt. Du warst schneller als ich.:) +1 – Tomalak

7

Es dauert 30 Minuten, um 500.000 Zeilen aus einer CSV zu importieren?

Haben Sie darüber nachgedacht, MySQL die Arbeit abnehmen zu lassen? Es gibt LOAD DATA INFILE, die mit CSV-Dateien unterstützt Umgang:

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
    LINES TERMINATED BY '\n'; 

Wenn die Datei nicht ganz in der richtigen Form ist direkt in die Zieltabelle importiert werden, können Sie entweder PHP verwenden können, es vorher zu verwandeln, oder es LOAD in eine "Staging" -Tabelle und lassen Sie MySQL die notwendige Umwandlung handhaben —, welche schneller und bequemer ist. Als zusätzliche Option scheint es eine Möglichkeit zu geben, MySQL-Abfragen asynchron über die MySQL Native Driver for PHP (MYSQLND) auszuführen. Vielleicht können Sie diese Option auch erkunden. Dadurch können Sie die Leistung der Benutzeroberfläche erhalten.

+0

Es jetzt über mysql performace, im Batch-Prozess muss ich andere verwandte Tabellen aktualisieren, es ist nicht einfügen, sondern aktualisieren, Status der Anwendungen, Zahlungstransaktionen, es dauert wirklich lange Zeit, coz ich habe einige Code-Logik zu tun, Erstellen Sie beispielsweise einige Datensätze in verknüpften Tabellen, informieren Sie Kunden (E-Mail-Nachrichten werden in die E-Mail-Warteschlange gestellt). Also ich denke, es mit php exec zu tun, ich laufe nur als Hintergrund-Prozess und lassen Sie es sich Zeit, um den Job zu beenden. Ich kann es nicht mit Cron tun, denn dies ist unter Benutzerkontrolle, Ein Benutzer klicken Sie auf Prozess Schaltflächen und später können Protokolle überprüfen, um den Prozessstatus zu sehen. Danke Tomalak für Ihre Antwort. – taras

+0

Es jetzt über mysql performace = Es geht nicht um mysql performace – taras

+1

Ich sehe. Ich ging von Ineffizienz aus, aber wenn es viel Arbeit kostet, dauert es natürlich einige Zeit. Viel Glück! :) – Tomalak

0

ich es mit cron cant do, Coz dies unter Benutzersteuerung ist, kann ein Benutzer klicken Prozess Buttons und später auf Protokolle überprüfen Prozessstatus

Wenn der Benutzer drückt die Taste, um zu sehen, stellen ein Flag in einer Tabelle in der Datenbank. Dann lassen Sie Ihren Cron-Job nach dieser Flagge suchen. Wenn es da ist, fange an zu verarbeiten, sonst nicht. I anwendbar, könnten Sie die gleiche Tabelle verwenden, um eine Art Status-Update (z. B. xx% getan), so dass der Benutzer ein Feedback über den Fortschritt hat.