2016-03-17 12 views
6

Tôi đang cố gắng chèn bản ghi vào DB sau, và mất khoảng 3 giờ trong khi mất 40 giây bằng cách sử dụng lệnh python psycopg2 và cursor.copy_fromChèn các bản ghi tệp vào db postgres bằng cách sử dụng jjc clojure mất nhiều thời gian so với python psycopg2

Mã của tôi sai, sử dụng clojure.java.jdbc/db-do-prepared cũng mất khoảng 3 giờ nữa. Xin vui lòng giúp đỡ!

Kích thước là 175 triệu và nó có 409.854 hồ sơ

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

Trả lời

3

Đây có thể là do không sử dụng trạm trộn trong phiên bản Clojure của bạn. Bạn chèn từng hàng một từng kích hoạt cam kết.

Nếu bạn muốn thực hiện điều đó ở Clojure, bạn cần phải partition hàng từ tệp CSV và insert! mỗi đoạn dưới dạng một lô cam kết. Bạn cần phải sử dụng phiên bản tinh thần cuối cùng chấp nhận nhiều số col-val-vec s. Mẫu mã (không được chọn, chỉ để hiển thị các ý tưởng):

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

Nếu bạn không cần phải làm điều đó trong Clojure sau đó sử dụng lệnh psql's COPY dường như là lựa chọn dễ dàng nhất và nhanh nhất:

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

Tôi đang sử dụng Clojure phiên bản 1.8.0, bạn có thể chia sẻ một ví dụ về cách nó có thể được thực hiện trong clojure –

+0

Tôi đã thêm một ví dụ mã trong Clojure - kiểm tra nó như tôi đã không chạy nó. –

+0

Vâng, tôi đã sử dụng lệnh Sao chép PSQL mà bạn đề xuất, thậm chí không cần phải đúc từng trường, điều này thực sự dễ dàng và nhanh hơn. Cảm ơn –

Các vấn đề liên quan