我的查询基本上是一个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
Run Code Online (Sandbox Code Playgroud) 我试图从一个Postgre数据库移动5,000,000行到另一个.两个连接都在Hikari CP连接池中.
我经历了很多文档和帖子.它给我留下了下面的代码.但它并不真正有用:
(jdbc/with-db-connection [tx {:datasource source-db}]
(jdbc/query tx
[(jdbc/prepare-statement (jdbc/get-connection tx)
answer-sql
{:fetch-size 100000})]
{:result-set-fn (fn [result-set]
(jdbc/insert-multi!
{:datasource target-db}
:migrated_answers
result-set))}))
Run Code Online (Sandbox Code Playgroud)
我尝试了很多不同的形式.jdbc/with-db-transaction或者我能想到的任何其他东西都没有多大帮助.
很多教程和帖子只提到了如何整体处理结果的方式.对于进入RAM的小桌子来说绝对可以,但它看起来很快.但这种情况并非如此.
因此,当我正确使用:fetch-size并且我的RAM没有爆炸(hocus pocus)比传输IS非常慢时,两个连接在DB端的"活动"和"事务中的空闲"状态之间切换.我从没等过这么久才发现任何实际转移的数据!
当我在Talend Open Studio(生成Java代码的ETL工具)中创建这个简单批处理时,它会在5分钟内传输所有数据.并且光标大小"也"设置为100000.我认为Clojure的干净代码应该更快.
我得到的最快结果是使用下面的代码.我认为这是因为:as-array参数.如果我不使用:max-rows参数内存爆炸,因为它没有被懒惰地处理,所以我不能将它用于整个transfet.为什么?我不明白这里的规则.
(jdbc/with-db-transaction [tx {:datasource source-db}]
(jdbc/query tx
[(jdbc/prepare-statement (:connection tx)
answer-sql
{:result-type :forward-only
:concurrency :read-only
:fetch-size 2000
:max-size 250000})]
{:as-arrays? true
:result-set-fn (fn [result-set]
(let [keys (first result-set)
values (rest result-set)]
(jdbc/insert-multi!
{:datasource dct-db}
:dim_answers
keys values)))}))
Run Code Online (Sandbox Code Playgroud)我将非常感谢我明显缺少的任何帮助或信息.