我正在尝试将记录插入 postgres 数据库,这大约需要 3 个小时,而使用 python psycopg2 和 cursor.copy_from 方法需要 40 秒
我的代码有什么问题,使用 clojure.java.jdbc/db-do-prepared 也需要大约 3 个小时。 请帮忙!
文件大小为175M,有409,854条记录
(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))))
最佳答案
这可能是因为您的 Clojure 版本中没有使用批处理。您逐行插入每行触发提交。
如果您想在 Clojure 中执行此操作,则需要从 CSV 文件和 insert!
中分区
行每个 block 作为一批提交。您需要使用接受多个 col-val-vec
的最后一个 arity 版本。示例代码(未检查,只是为了展示想法):
(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))))
如果您不必在 Clojure 中执行此操作,则使用 psql
's COPY
命令似乎是最简单和最快的选择:
COPY records FROM '/path/to/foo.txt' WITH (FORMAT csv, DELIMITER ',', NULL 'NULL');
关于java - 与 python psycopg2 相比,使用 clojure jdbc 将文件记录插入 postgres db 需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36058957/