Bulk / Batch Update / Upsert in PostgreSQL

Schreibe ich eine Django-ORM, sensible Erweiterung, die versucht, cache-Modelle und verschieben Sie das Modell speichern, bis zum Ende der Transaktion. Es ist alles fast fertig, allerdings stieß ich auf eine unerwartete Schwierigkeit in der SQL-syntax.

Ich bin nicht viel von einem DBA, sondern von dem, was ich verstehe, Datenbanken nicht wirklich effizient arbeiten für viele kleine queries. Paar größere Abfragen sind viel besser. Es ist zum Beispiel besser, um große batch-Einsätze (sagen wir 100 Zeilen auf einmal) anstatt 100 Einzeiler.

Nun, von dem, was ich sehen kann, ist SQL nicht wirklich irgendwelche Anweisung zum ausführen einer batch-update auf eine Tabelle. Der Begriff scheint verwirrend so, ich werde erklären, was ich damit meine. Ich habe ein array beliebige Daten, jeder Eintrag beschreibt eine einzelne Zeile in einer Tabelle. Ich möchte zu aktualisieren, bestimmte Zeilen in der Tabelle, die jeweils mit Daten aus den entsprechenden Eintrag im array. Die Idee ist sehr ähnlich wie eine Batchdatei einfügen.

Zum Beispiel: Meine Tabelle zwei Spalten "id" und "some_col". Jetzt ist das array zur Beschreibung der Daten für eine batch-update besteht aus drei Einträge (1, 'first updated'), (2, 'second updated'), und (3, 'third updated'). Vor dem aktualisieren der Tabelle Zeilen enthält: (1, 'first'), (2, 'second'), (3, 'third').

Ich stieß auf dieses post:

Warum sind batch-inserts/updates schneller? Wie kann der batch-updates funktionieren?

scheint das zu tun, was ich will, aber ich kann nicht wirklich herausfinden, die syntax am Ende.

Konnte ich auch löschen Sie alle Zeilen, die aktualisiert werden müssen, und legen Sie Sie unter Verwendung einer Batchdatei einfügen, allerdings finde ich es schwer zu glauben, dass dies tatsächlich besser.

Ich die Arbeit mit PostgreSQL-8.4, so dass einige gespeicherte Prozeduren sind auch hier möglich. Aber da ich Plane, open-source-Projekt schließlich nicht mehr tragbare Ideen oder Möglichkeiten zu tun, die gleiche Sache auf einem anderen RDBMS sind das meiste willkommen.

Follow-up-Frage: Wie man eine batch - "insert-oder update"/"upsert" - Anweisung?

Testergebnisse

Habe ich durchgeführt 100x mal 10 insert-Operationen, die sich über 4 verschiedene Tabellen (also 1000 inserts in der Summe). Getestet habe ich auf Django 1.3 mit einer PostgreSQL-8.4-backend.

Dies sind die Ergebnisse:

  • Alle Operationen durch Django ORM - jeder pass ~2.45 Sekunden,
  • Die gleichen Operationen, aber dies ohne Django ORM - jeder pass ~1.48 Sekunden,
  • Nur insert-Operationen, ohne Abfragen an die Datenbank, die für das sequence-Werte ~0.72 Sekunden,
  • Nur insert-Operationen, durchgeführt in Blöcken von 10 (100 Blöcke insgesamt) ~0.19 Sekunden,
  • Nur insert-Operationen, eine große Ausführung block ~0.13 Sekunden.
  • Nur insert-Operationen, über 250 Aussagen pro block, ~0,12 Sekunden.

Fazit: führen Sie so viele Operationen wie möglich in einer einzigen Verbindung.execute(). Django selbst stellt einen erheblichen Aufwand.

Disclaimer: ich habe nicht einführen, Indizes, abgesehen von Standard-Primärschlüssel-Indizes, so dass insert-Operationen könnte möglicherweise schneller ausgeführt werden, weil die.

Kommentar zu dem Problem - Öffnen
+1, da habe ich gelernt, dass "upsert" ist ein Wort, (es ist auch auf wikipedia ) Kommentarautor: SingleNegationElimination
Können Sie uns zeigen, den Aussagen, die Sie ausgeführt werden? Ich bin ein bisschen verwirrt durch den Begriff "batch-update"? Kannst du nicht alle updates mit einem einzigen UPDATE-Anweisung? Mit 9.1 Sie können auch UPDATE-und INSERT in einem Arbeitsgang mit beschreibbaren CTEs Kommentarautor: a_horse_with_no_name

InformationsquelleAutor der Frage julkiewicz | 2011-08-11

Schreibe einen Kommentar