java - 与 python psycopg2 相比,使用 clojure jdbc 将文件记录插入 postgres db 需要很长时间

标签 java python postgresql jdbc clojure

我正在尝试将记录插入 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/

相关文章:

java - 记录层次结构并将 Spark log4j Logger 附加到其中

python - 如何使用 python 获取 JSON 对象中的值/内容

java - 使用java和intellij连接到postgresql的问题

sql - 从多个 TableView PostgreSQL 中获取游标

java - 跳水比赛-Java程序

python - 根据长度向 df.Column 中的字符串添加尾随 0

java - 搜索文本中的字符串模式

python - 尝试在 flask 上插入时无法解码json对象

java - 检查是否加载了 jar 文件?

java - 将 Joda 日期时间字符串转换为 Java.Sql.TimeStamp 以进行 INSERT