私はデータベースから何百万もの行を読み込み、テキストファイルに書き込もうとしています。clojure.java.jdbc /大規模な結果を遅く照会
これはdatabase dump to text file with side effects
私の問題は、今のプログラムが完了するまでのログが起こらないということのようです私の質問の続きです。私が遅れて処理していないという別の指標は、プログラムが終了するまでテキストファイルがまったく書き込まれないということです。
IRCのヒントによると、コードのclojure.java.jdbc/query
領域では、:result-set-fn
とデフォルトとしてdoall
とする必要があるようです。
これをfor
関数に置き換えようとしましたが、結果セット全体をメモリにプルするため、メモリ消費量が高いことがわかりました。
doall
のようにすべてを取り込まない:result-set-fn
をどうすればよいですか? -main
実行が終了したら、プログラムを実行している間に徐々にログファイルを書き込んで、すべてをダンプすることはできますか?
(let [
db-spec local-postgres
sql "select * from public.f_5500_sf "
log-report-interval 1000
fetch-size 100
field-delim "\t"
row-delim "\n"
db-connection (doto (j/get-connection db-spec) (.setAutoCommit false))
statement (j/prepare-statement db-connection sql :fetch-size fetch-size)
joiner (fn [v] (str (join field-delim v) row-delim))
start (System/currentTimeMillis)
rate-calc (fn [r] (float (/ r (/ (- (System/currentTimeMillis) start) 100))))
row-count (atom 0)
result-set-fn (fn [rs] (lazy-seq rs))
lazy-results (rest (j/query db-connection [statement] :as-arrays? true :row-fn joiner :result-set-fn result-set-fn))
]; }}}
(.setAutoCommit db-connection false)
(info "Started dbdump session...")
(with-open [^java.io.Writer wrtr (io/writer "output.txt")]
(info "Running query...")
(doseq [row lazy-results]
(.write wrtr row)
))
(info (format "Completed write with %d rows" @row-count))
)
、作られた:結果タイプの順方向のみ、カーソルを追加しました読み込み専用にし、フェッチサイズを1000、そして100に設定しました。大きな結果セットをフェッチしようとすると、jvmヒープサイズが不足しています。私は新しいコードを含めるために上記の私の質問を更新しました...私はこの時点で何が熱望することができたのかを失っています... – joefromct
@joefromct、自動コミットを無効にしてみてください - '(.setAutoCommit db-connection false) '。私は答えのサンプルコードに追加しました。一方、難しい点の1つは、 'setFetchSize'はドライバのヒントに過ぎないということです([API docs](http://docs.oracle.com/javase/1.5.0/docs/api/java/)。 sql/Statement.html#setFetchSize(int)))どのように解釈されるかはドライバによって異なる可能性があります。しかし、PostgreSQLの[JDBC docs](http://jdbc.postgresql.org/documentation/head/query.html)は、サポートされていることを示しているので、ちょうどよい命題を見つける必要があると思います。 – jbm
明確にするために、 'setFetchSize'は、' prepare-statement'が ':fetch-size'引数に基づいて内部的に呼び出すメソッドです。 – jbm