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.
InformationsquelleAutor der Frage julkiewicz | 2011-08-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe 3 Strategien für batch-Transaktionen arbeiten:
flush()
Methode gegen die HibernateSession
, nicht die zugrunde liegende JDBC-Verbindung. Es leistet das gleiche wie JDBC-Batchverarbeitung.Übrigens, Hibernate unterstützt auch eine Stapelverarbeitung Strategie in die Sammlung Holen. Wenn Sie kommentieren eine Sammlung mit
@BatchSize
, beim abrufen von Verbänden, Hibernate verwendenIN
statt=
, was zu wenigerSELECT
Aussagen zu laden, bis die Sammlungen.InformationsquelleAutor der Antwort atrain
Bulk insert
Können Sie die bulk insert von drei Spalten durch Ketema:
Wird es:
Ersetzen Sie die Werte durch Platzhalter:
Haben Sie das übergeben von arrays oder Listen als Argumente für diese Abfrage. Dies bedeutet, dass Sie tun können, riesige Massen-inserts, ohne dabei die string-Verkettung (und alle seine hazzles und Gefahren: sql-injection und Angabe der Hölle).
Bulk update
PostgreSQL Hinzugefügt hat, die AUS der extension zu AKTUALISIEREN. Sie können es verwenden, auf diese Weise:
Handbuch fehlt eine gute Erklärung, aber es ist ein Beispiel für die postgresql-admin mailing list. Ich habe versucht, zu erläutern:
Gibt es auch andere Beiträge auf StackExchange erklärt
UPDATE...FROM..
mit einemVALUES
- Klausel anstelle einer Unterabfrage. Sie können einfacher gelesen werden, sondern sind beschränkt auf eine Feste Anzahl von Zeilen.InformationsquelleAutor der Antwort hagello
Großteil der Einsätze wie folgt durchgeführt:
Einfügen 3 Zeilen.
Mehreren Update ist definiert durch die SQL-standard, aber nicht implementiert PostgreSQL.
Zitat:
Referenz: http://www.postgresql.org/docs/9.0/static/sql-update.html
InformationsquelleAutor der Antwort Ketema
es ist ziemlich schnell zu füllen json-in-recordset (postgresql 9.3+)
InformationsquelleAutor der Antwort nogus
Schalten Sie autocommit und einfach ein commit am Ende. In plain SQL bedeutet dies die Erteilung, BEGINNEN am Anfang und BEGEHEN am Ende. Sie würden erstellen müssen, Funktion um eine tatsächliche upsert.
InformationsquelleAutor der Antwort aliasmrchips