2016-03-17 1 views
6

ich Datensätze in Postgres DB einzufügen versuchen, und seine etwa 3 Stunden dauern, während es 40 Sekunden mit Python psycopg2 und cursor.copy_from MethodeDatei einfügen Datensätze in Postgres DB clojure jdbc mit nehmen lange Zeit im Vergleich zu Python psycopg2

nimmt

Was ist falsch mit meinem Code, mit clojure.java.jdbc/db-do-prepared dauert auch etwa 3 Stunden. Bitte helfen!

Dateigröße ist 175M und es hat 409.854 Datensätze

(defn- 
    str<->int [str] 
    (let [n (read-string str)] 
    (if (integer? n) n))) 

(with-open [file (reader "/path/to/foo.txt")] 
    (try 
     (doseq [v (clojure-csv.core/parse-csv file)] 

     (clojure.java.jdbc/insert! db :records 
         nil 
         [(v 0) (v 1) (v 2) (str<->int (v 3))])) 
     (println "Records inserted successfully") 
     (Exception e 
     (println (.getNextException e) e)))) 

Antwort

3

Es ist wahrscheinlich wegen nicht Dosierung in Ihrer Clojure-Version. Sie fügen Zeilen nacheinander ein, die jeweils das Commit auslösen.

Wenn Sie es in Clojure als partition Zeilen aus CSV-Dateien und insert! tun wollen, jedes Stück als ein Batch-Commit. Sie müssen die letzte Arity-Version verwenden, die mehrere col-val-vec s akzeptiert. Beispielcode (nicht geprüft, sondern nur die Idee zu zeigen):

(defn row->col-spec [row] 
    [(v 0) (v 1) (v 2) (str<->int (v 3))]) 

(with-open [csv-file (reader "/path/to/foo.txt")] 
    (try 
    (->> csv-file 
     (clojure-csv.core/parse-csv) 
     (map row->col-spec) 
     (partition 50) 
     (map (fn [batch] clojure.java.jdbc/insert! db :records ["col1" "col2" "col3" "col4"] batch)) 
     (dorun)) 
    (catch Exception e 
     (println e)))) 

Wenn Sie müssen es dann in Clojure nicht zu tun mit psql's COPY Befehl scheint die einfachste und schnellste Möglichkeit zu sein:

COPY records FROM '/path/to/foo.txt' WITH (FORMAT csv, DELIMITER ',', NULL 'NULL'); 
+1

Ich benutze Clojure Version 1.8.0, können Sie ein Beispiel, wie es in clojure getan werden kann –

+0

Ich habe ein Codebeispiel in Clojure hinzugefügt - testen Sie es, wie ich es nicht ausgeführt habe. –

+0

Nun, ich habe den PSQL Copy-Befehl, den Sie vorgeschlagen haben, verwendet, nicht einmal jedes Feld zu werfen, das ist in der Tat einfacher und schneller. Vielen Dank –

Verwandte Themen