2016-07-14 12 views
0

≈105 Sekunden pro 1 Million Zeilen in PostgreSQL lokalen Datenbank in Tabelle mit 2 Indizes und 4 Spalten einzufügen ist es langsam oder schnell?Einfügen von Daten in PostgreSQL aus Python

Python-Code:

import os 
import pandas as pd 
from concurrent.futures import ThreadPoolExecutor, as_completed 
from sqlalchemy import create_engine 

num = 32473068 
batch = 1000000 

def main(data): 
    engine = create_engine('postgresql://***:****' + host + ':5432/kaggle') 
    data.to_sql(con=engine, name=tbl_name, if_exists='append', index=False) 

for i in range(0, num, batch): 
    data = pd.read_csv(data_path+'app_events.csv', skiprows=i, nrows=batch) 
    data.columns = ['event_id', 'app_id', 'is_installed', 'is_active'] 
    data = data.reset_index(drop=True) 
    batchSize = 10000 
    batchList = [data.iloc[x:x + batchSize].reset_index(drop=True) for x in range(0, len(data), batchSize)] 
    with ThreadPoolExecutor(max_workers=30) as executor: 
     future_to_url = {executor.submit(main, d): d for d in batchList} 
     for k, future in enumerate(as_completed(future_to_url)): 
      url = future_to_url[future] 
+1

Postgres hat einen speziellen Befehl zum Importieren von CSV-Dateien 'COPY' - nichts sollte schneller sein. –

+1

pg_bulkload ist eigentlich schneller – d1ll1nger

+0

Zusätzlich zu @ user2189731 ist hervorragende Punkt über die Aktivierung ** use_batch_mode = True ** in Ihrer SQLAlchemy in Ihrer Engine Instanziierung Ich würde vorschlagen, dass Sie Multi-Threading für diese Aufgabe überspringen. Das ist unwahrscheinlich, dass es eine vorteilhafte Nebenläufigkeit bietet und verliert wahrscheinlich weit mehr, um die Konkurrenz zu sperren, als Sie gewinnen würden. –

Antwort

1

Kann nicht kommentieren so klebte ich als Antwort.

Es hängt auch von Ihrer Hardware ab. Als Referenz verwendet mein alter I5-Laptop mit HDD ~ 300s, um 0,1M Zeilen (ungefähr 200-300 Megabyte) einzufügen.

Ich habe von anderen ähnlichen Fragen gelernt, dass große Werte in Bulks aufgeteilt werden, wenn der Befehl insert() beschleunigt werden konnte. Da Sie Pandas benutzen, nehme ich an, dass es bereits eine gewisse Optimierung hat. Aber ich schlage vor, dass Sie einen schnellen Test machen, um zu sehen, ob es auch hilft.

Bearbeiten: Pandas tatsächlich nicht optimierte Einfügebefehl verwendet. Siehe (to_sql + sqlalchemy + copy from + postgresql engine?). Daher sollten Bulk-Insert- oder andere Methoden verwendet werden, um die Leistung zu verbessern.

Edit2: SQLalchemy 1.2 verwendet Masseneinfügung, wenn Sie Ihre Engine mit dem Parameter "use_batch_mode = True" initialisieren. Ich habe 100X Beschleunigung auf meinem I5 + HDD Laptop gesehen! Bedeutung mit 0.1M Aufzeichnung, ursprünglich dauerte es 300s und jetzt ist es 3s !!. Wenn dein Computer besser ist als meiner, wette ich, dass du diese enorme Beschleunigung mit deinen 1M-Schallplatten sehen kannst.