2009-04-02 11 views
3

Ich habe ein PHP-Skript, das eine API-Methode aufruft, die 6k + -Ergebnisse problemlos zurückgeben kann.INSERT 6000 Zeilen - Best Practice

Ich benutze PEAR DB_DataObject, um jede Zeile in einer foreach-Schleife in den DB zu schreiben.

Das obige Skript verarbeitet im Batch 20 Benutzer gleichzeitig - und obwohl einige nur wenige Ergebnisse von der API haben, werden andere mehr haben. Worst Case ist, dass alle 1000 Ergebnisse haben.

Die Schleife zum Aufruf der API scheint in Ordnung zu sein, Chargen von 20 alle 5 Minuten funktioniert gut. Meine einzige Sorge ist 1000 von mysql INSERTs für jeden Benutzer (mit einer langen Pause zwischen jedem Benutzer für frische API-Aufrufe)

Gibt es eine gute Möglichkeit, dies zu tun? Oder mache ich es gut ?!

+0

Ich fand [Dieser Beitrag helfen könnte] [1] es das gleiche Problem lösen Ich denke [1]: http://stackoverflow.com/questions/1176352/pdo-prepared-inserts-multiple -rows-in-single-Abfrage –

Antwort

1

Nun, produziert Ihre Methode mehr Last als Sie verarbeiten können? Wenn es funktioniert, sehe ich keinen Grund, es von Hand zu ändern.

4

Nun, der schnellste Weg, es zu tun wäre, mit vielen Werten einer Insert-Anweisung zu tun, wie folgt aus:

INSERT INTO mytable (col1, col2) VALUES ((?,?), (?,?), (?,?), ...) 

Aber das würde wahrscheinlich erfordern die DB_DataObject Methode Notwasserung Sie jetzt verwenden. Sie müssen nur die Leistungsvorteile abwägen, die sich daraus ergeben, im Vergleich zu den Vorteilen der Benutzerfreundlichkeit von DB_DataObject.

2

Wie Kalium sagte, überprüfen, wo der Engpass ist. Wenn es wirklich die Datenbank ist, könnten Sie versuchen, die Massenimport-Funktion einige DBMS bieten.

In DB2 heißt es beispielsweise LOAD. Es funktioniert ohne SQL, liest aber direkt aus einer Named Pipe. Es ist besonders entworfen, um schnell zu sein, wenn Sie eine große Anzahl von neuen Zeilen in die Datenbank bringen müssen. Es kann so konfiguriert werden, dass Überprüfungen und Indexerstellung übersprungen werden, wodurch es noch schneller wird.

0

Datenbankabstraktionsschichten fügen normalerweise eine recht ordentliche Menge an Overhead hinzu. Ich habe festgestellt, dass es in PHP zumindest einfacher ist, eine einfache mysql_query aus Gründen der Geschwindigkeit zu verwenden, als es ist, um Ihre Bibliothek der Wahl zu optimieren.

Wie Eric P und weinzierl.name haben gesagt, mit einem mehrzeiligen Einsatz oder LOAD erhalten Sie die beste direkte Leistung.

0

Ich habe ein paar Ideen, aber Sie müssen sie mit Tests verifizieren.

Wenn die Tabelle, in die Sie einfügen, Indexe enthält, versuchen Sie sicherzustellen, dass sie für Einfügungen optimiert sind.

Check out Optimierungsmöglichkeiten hier: http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html

Betrachten Mysqli direkt oder Birne :: MDB2 oder PDO. Ich verstehe, dass Pear :: DB ziemlich langsam ist, obwohl ich PEAR selbst nicht benutze, also kann ich das nicht verifizieren.

0

MySQL LOAD DATEN INFILE Funktion ist wahrscheinlich der schnellste Weg, um zu tun, was Sie wollen.

Sie können sich das Kapitel Speed of INSERT statements zur MySQL-Dokumentation ansehen.

Es geht um eine Menge Weg, um INSERTING in MySQL zu verbessern.

0

Ich glaube nicht, dass ein paar tausend Datensätze Ihre Datenbank belasten sollten; Sogar mein Laptop sollte es gut handhaben. Ihre größte Sorge könnte sein (kommen) gigantische Tabellen, wenn Sie keine Bereinigung oder Partitionierung tun. Vermeiden Sie vorzeitige Optimierung auf diesem Teil.

Wie für Ihre Methode, stellen Sie sicher, dass Sie jeden Benutzer (oder Batch) in einer separaten Transaktion ausführen. Wenn Sie MySQL verwenden, stellen Sie sicher, dass Sie innodb verwenden, um unnötiges Sperren zu vermeiden. Wenn Sie bereits innodb/postgres/andere Datenbank verwenden, die Transaktionen unterstützt, sehen Sie möglicherweise eine erhebliche Leistungssteigerung.

Verwenden Sie COPY (zumindest auf Postgres - unsicher über MySQL).

Stellen Sie sicher, dass Ihre Tabelle ordnungsgemäß indiziert ist (einschließlich Entfernen nicht verwendeter Tabellen). Indizes beeinträchtigen die Geschwindigkeit.

Denken Sie daran, regelmäßig zu optimieren/vakuumieren.