我有一个查询,基本上是一个select *
。 在发展该表仅是30000行,但在生产中它会大得多。 所以我想懒洋洋地消耗此查询。 为什么不低于查询懒惰? 我使用的是Postgres 9.5.4.1。
(do
(def pg-uri {:connection-uri "jdbc:postgresql://localhost/..."})
(def row (atom 0))
(take 10 (clojure.java.jdbc/query
pg-uri
["select * from mytable"]
{:fetch-size 10
:auto-commit false
:row-fn (fn [r] (swap! row inc))}))
@row) ;;=> 300000
clojure.java.jdbc
支持大型结果迟缓处理本身设置这些天(这里的其他答案早是原生支持)。 在这里看到关于它的社区文档:
http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html#processing-a-result-set-lazily
特别是,看到其他选项? 部分你可能需要特定于数据库的调整。 您可以指定:auto-commit? false
:auto-commit? false
的,将打开一个新的连接,您可以指定任何功能:fetch-size
和任何查询相关功能的各个光标控制。 见什么PostgreSQL的可能需要细节这个StackOverflow的问题和答案:
Java的JDBC忽略的setFetchSize?
目前,你必须在挖clojure.java.jdbc
源或prepare-statement
参考文档获取更多的这些选项。 我继续对社区工作的文件表面所有信息。
首先,看看https://jdbc.postgresql.org/documentation/83/query.html#query-with-cursor 。
解决了它这样。
(jdbc/with-db-transaction [tx connection]
(jdbc/query tx
[(jdbc/prepare-statement (:connection tx)
"select * from mytable"
{:fetch-size 10})]
{:result-set-fn (fn [result-set] ...)}))
其中:result-set-fn
是消耗懒惰结果集的函数。
with-db-transaction
需要照顾的autoCommit
设置为false
。 :fetch-size
不从通过query
,所以你必须做出prepare-statement
自己。
你不需要交易,并准备语句的东西上面。 它是利用的:result-set-fn
引起懒惰序列被消耗。 你可能想用的是:row-fn
代替。
有关详情请参阅Clojure的食谱。 打印版本也已经推出,我建议。
的jdbc /查询功能具有控制它如何构建返回的结果集多种可选关键字参数。 的:结果集-FN参数指定被返回之前,被施加到整个结果集的函数(懒惰序列)。 默认参数是DOALL功能:
(defn hi-lo [rs] [(first rs) (last rs)])
;; Find the highest- and lowest-cost fruits
(jdbc/query db-spec
["select * from fruit order by cost desc"]
:result-set-fn hi-lo)
;; -> [{:grade nil, :unit nil, :cost 77, :appearance nil, :name "Kumquat"}
;; {:grade 1.4, :unit nil, :cost 10, :appearance "rotten", :name "Tomato"}]
的:行-FN参数指定作为结果构成的,即施加到每个结果行的函数。 默认参数是身份的功能:
(defn add-tax [row] (assoc row :tax (* 0.08 (row :cost))))
(jdbc/query db-spec
["select name,cost from fruit where cost = 12"]
:row-fn add-tax)
;; -> ({:tax 0.96, :cost 12, :name "Plum"} {:tax 0.96, :cost 12, :name "Fig"})