2016-09-30 1 views
2

Ich schreibe ein Programm zum Laden von Daten in eine bestimmte Datenbank. Das ist, was ich jetzt tue ...Geschwindigkeit Verbesserung in Postgres INSERT Befehl

 conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName) 
     cur = conn.cursor() 

     lRows = len(rows) 
     i, iN = 0, 1000 
     while True: 

      if iN >= lRows: 
       # write the last of the data, and break ... 
       iN = lRows 
       values = [dict(zip(header, r)) for r in rows[i:iN]] 
       cur.executemany(insertString, values) 
       conn.commit() 
       break 

      values = [dict(zip(header, r)) for r in rows[i:iN]] 
      cur.executemany(insertString, values) 
      conn.commit() 

      i += 1000 
      iN += 1000 

     cur.close() 
     conn.close() 

Ich bin mir bewusst über this Frage über die Verwendung des COPY Befehl. Bevor ich die Dateien in eine Datenbank hochladen kann, muss ich jedoch eine Buchhaltung für meine Dateien erstellen. Daher benutze ich Python auf diese Weise.

Ich habe ein paar Fragen, wie schneller machen Dinge ...

  1. Wäre es besser (oder möglich), viele cur.executemany() Aussagen und eine einziges conn.commit() am Ende zu tun? Das bedeutet, dass ich eine einzelneconn.commit() Aussage kurz vor der cur.close() Anweisung setzen.
  2. Ich habe immer andere Leute benutzen gesehen cur.executemany() für Chargen wie 1000 oder so Aufzeichnungen. Ist das in der Regel der Fall oder ist es möglich, einfach einen cur.executemany() für die gesamte Menge von Datensätzen zu machen, die ich aus der Datei gelesen habe. Ich hätte möglicherweise Hunderttausende Datensätze oder vielleicht etwas mehr als eine Million Datensätze. (Ich habe genügend RAM, um die gesamte Datei im Speicher zu speichern). Wie kann ich die obere Grenze der Anzahl der Datensätze kennen, die ich gleichzeitig hochladen kann?
  3. Ich mache eine neue Verbindung zur Datenbank für jede Datei, die ich öffne. Ich mache das, weil dieser Prozess mich viele Tage braucht, um abzuschließen, und ich möchte nicht, dass Probleme mit der Verbindung die Gesamtheit der Daten beschädigen, wenn die Verbindung zu irgendeinem Zeitpunkt verloren ist. Ich habe über tausend Dateien, die ich durchlaufen muss. Sind diese tausend Verbindungen, die wir machen, ein wesentlicher Teil der Zeit, die für den Prozess benötigt wird?
  4. Gibt es noch andere Dinge, die ich im Programm mache, die ich nicht tun sollte, die die gesamte Zeit für den Prozess verkürzen können?

Vielen Dank für jede Hilfe, die ich bekommen kann. Entschuldige, dass die Fragen so grundlegend sind. Ich beginne gerade mit Datenbanken in Python, und aus irgendeinem Grund scheint es mir momentan keine definitive Antwort auf diese Fragen zu geben.

Antwort

1
  1. Wie Sie bei S.3 erwähnt sind Sie besorgt über die Datenbankverbindung, die brechen könnten, wenn Sie also ein conn.commit() nur nach allen Einsätzen, können Sie einfach lose bereits eingeführt, aber keine Daten verpflichtet, wenn Ihre Verbindung bricht vor conn.commit(). Wenn Sie conn.commit() nach jedem cur.executemany() tun, werden Sie nicht alles verlieren, nur die letzte Partie. Es liegt also an Ihnen und hängt von einem Workflow ab, den Sie unterstützen müssen.

  2. Die Anzahl der Datensätze pro Charge ist ein Kompromiss zwischen der Einführungsgeschwindigkeit und anderen Dingen. Sie müssen einen Wert wählen, der Ihren Anforderungen entspricht. Sie können Ihr Skript mit 1000 Datensätzen pro Batch mit 10000 pro Batch testen und den Unterschied prüfen. Der Fall innerhalb einer cur.executemany() ganze Datei eingefügt haben einen Vorteil einer Unteilbarkeit: wenn es ausgeführt wurde, das heißt, alle Datensätze aus dieser speziellen Datei eingefügt wurden, so dass wir wieder auf p. 1.

  3. denke ich, die Kosten für eine neue Verbindung in Ihrem Fall zur Gründung spielt eigentlich keine Rolle. Angenommen, es dauert eine Sekunde, um eine neue Verbindung herzustellen. Bei 1000 Dateien werden innerhalb von Tagen 1000 Sekunden für die Verbindung verbraucht.

  4. Das Programm selbst sieht gut aus, aber ich würde Sie noch empfehlen, einen Blick auf COPY TO Befehl mit UNLOGGED oder TEMPORARY Tabellen zu nehmen, es wird wirklich Ihre Importe beschleunigen.

Verwandte Themen