2016-03-17 8 views
6

próbuję wstawić rekordów do PostgreSQL DB, a jego biorąc około 3 godzin, podczas gdy trwa 40seconds użyciu Pythona psycopg2 i sposobu cursor.copy_fromwstawiania rekordów pliku do PostgreSQL DB wykorzystujące Clojure JDBC trwa długo w porównaniu do Pythona psycopg2

Co jest nie tak z moim kodem, użycie clojure.java.jdbc/db-do-prepared również zajmuje około 3 godzin. Proszę o pomoc!

Rozmiar pliku jest 175M i ma 409,854 rekordy

(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)))) 

Odpowiedz

3

Jest to prawdopodobnie ze względu na nie za pomocą dozowania w wersji Clojure. Wstawiasz rzędy po kolei, uruchamiając commit.

Jeśli chcesz zrobić to w Clojure, musisz partition wierszy z plików CSV i insert! każdej porcji jako jedno zatwierdzenie partii. Musisz użyć ostatniej wersji arity akceptującej wiele s. col-val-vec. Przykładowy kod (nie zaznaczone, żeby pokazać ideę):

(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)))) 

Jeśli nie masz to zrobić w Clojure następnie za pomocą polecenia psql's COPY wydaje się być najprostszym i najszybszym rozwiązaniem:

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

Używam wersji Clojure 1.8.0, czy możesz udostępnić przykład jak to zrobić w clojure –

+0

Dodałem przykład kodu w Clojure - przetestuj go tak, jak go nie uruchomiłem. –

+0

Cóż, użyłem polecenia kopiowania PSQL, które zasugerowałeś, nawet nie musiałem rzutować każdego pola, to jest rzeczywiście łatwiejsze i szybsze. Dzięki –

Powiązane problemy