【发布时间】:2015-09-22 22:43:26
【问题描述】:
我在使用 clojure.java.jdbc 从 MySQL 数据库流式传输大型结果集时遇到问题。这就是我现在正在尝试的:
(defn etl! [query result-set-fn]
(jdbc/with-db-transaction [t-conn db-spec]
(let [conn (jdbc/get-connection t-conn)
statement (jdbc/prepare-statement conn query
:fetch-size Integer/MIN_VALUE
:concurrency :read-only
:result-type :forward-only)]
(jdbc/query conn [statement] :result-set-fn first))))
我也尝试过不使用事务并使用(.setAutoCommit conn False)(这对于 Postgres 是必需的)。根据 MySQL 文档,设置 fetch-size、concurrency 和 result-type 应该告诉 MySQL 一次交付一个结果,但这似乎没有发生;查询挂起,堆消耗稳定上升至少数百兆字节。
几年前有人问过类似的问题,但现在 clojure.java.jdbc 已弃用该答案: Streaming from MySQL with clojure.java.jdbc
有什么想法吗?
【问题讨论】:
-
我没玩过mysql但是最近用过Postgres。在那种情况下,使用 :result-set-fn 或 :row-fn 对我来说确实很懒惰。您可能希望尝试使用 Postgres 进行最小测试,看看是否能解决问题。此外,对于读取,我认为 (with-db-transaction ...) 没有任何好处
-
是的,我在工作中或多或少地在 postgres 中执行此操作,并且效果非常好。这可能是 MySQL 驱动程序的问题。我尝试交易的唯一原因是上面链接的另一个答案推荐了它,并且考虑到表面上让 MySQL 一次给你一个东西(MIN_VALUE 等)所需的仪式和咒语的数量,这似乎是合理的。在这种情况下,我使用 MySQL,因为我正在处理 wikipedia 数据,但此时将其迁移到 postgres 可能是值得的。