首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure.java.jdbc延迟查询

clojure.java.jdbc延迟查询
EN

Stack Overflow用户
提问于 2016-09-29 09:03:58
回答 3查看 2.2K关注 0票数 7

我有一个基本上是select *的查询。在开发中,这个表只有30000行,但是在生产中它会大得多。所以我想懒洋洋地使用这个查询。为什么下面的查询不懒惰?我正在使用Postgres 9.5.4.1。

代码语言:javascript
复制
(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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-29 16:44:47

clojure.java.jdbc支持本机对大型结果集的延迟处理(这里的其他答案早于本机支持)。请参阅这里的社区文档:

sql#处理-结果集-懒惰

特别是,请参阅附加选项?部分,了解您可能需要的特定于数据库的调整。可以在任何打开新连接的函数上指定:auto-commit? false,也可以在任何与查询相关的函数上指定:fetch-size和各种游标控件。有关StackOverflow可能需要什么的详细信息,请参阅下面的PostgreSQL问答:

JDBC忽略setFetchSize?

目前,要获得更多这样的选项,您必须深入clojure.java.jdbc源代码参考文献。我正在继续编写社区文档,以公开所有这些信息。

票数 8
EN

Stack Overflow用户

发布于 2016-09-29 15:59:48

首先,请参阅https://jdbc.postgresql.org/documentation/83/query.html#query-with-cursor

就这样解决了。

代码语言:javascript
复制
(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

票数 9
EN

Stack Overflow用户

发布于 2016-09-30 00:48:13

你不需要上面的交易和准备好的报表。正是:result-set-fn的使用导致了延迟序列的消耗。您可能打算使用:row-fn代替。

有关详细信息,请看“衣柜烹饪书”。还提供了打印版本,我建议这样做。

jdbc/query函数有几个可选的关键字参数,这些参数控制它如何构造返回的结果集。结果集-fn参数指定一个函数,该函数在返回之前应用于整个结果集(一个惰性序列)。默认参数是doall函数:

代码语言:javascript
复制
(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"}]

row -fn参数指定在构造结果时应用于每个结果行的函数。默认参数是identity函数:

代码语言:javascript
复制
(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"})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39765943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档