select ステートメントからデータベースの SQL ダンプをテキスト ファイルに書き込む関数を作成しようとしています。返されるボリュームは非常に大きくなる可能性があるため、できるだけ早くこれを行うことに関心があります。
大きな結果セットでは、書き込まれた行の総数と、最後の x 間隔以降に書き込まれた 1 秒あたりの行数を x 間隔ごとにログに記録する必要もあります。私は (with-open ) 中に実際に書き込みを行っている (map ) を持っているので、完了した行をログに記録するという副作用がそこで発生するはずです。(コード内のコメントを参照してください)。
私の質問は次のとおりです。
- 間隔中の「1 秒あたりの行数」と「これまでの合計行数」を書き込むにはどうすればよいですか?
- 大きな jdbc 結果セットをファイル (または名前付きパイプ、バルクローダーなど) に書き込む際に留意したい追加事項はありますか?
- (map ) 関数の周りの (doall ) はすべての結果を取得しますか?
オプションで幅固定は可能でしょうか?名前付きパイプからバルクローダーへのほうが速いと思います。トレードオフは、ダウンストリーム解析のための CPU 使用率の代わりにディスク i/o になります。ただし、これには、返された結果セットのイントロスペクションが必要になる場合があります (.getMetaData? を使用)。
(ns metadata.db.table-dump [:use [clojure.pprint] [metadata.db.connections] [metadata.db.metadata] [clojure.string :only (join)] [taoensso.timbre :only (debug info warn error set-config!)] ] [:require [clojure.java.io :as io ] [clojure.java.jdbc :as j ] [clojure.java.jdbc.sql :as sql] ] ) (set-config! [:appenders :spit :enabled?] true) (set-config! [:shared-appender-config :spit-filename] "log.log") (let [ field-delim "\t" row-delim "\n" report-seconds 10 sql "select * from comcast_lineup " joiner (fn [v] (str (join field-delim v ) row-delim ) ) results (rest (j/query local-postgres [sql ] :as-arrays? true :row-fn joiner )) ] (with-open [wrtr (io/writer "test.txt")] (doall (map #(.write wrtr %) ; Somehow in here i want to log with (info ) rows written so ; far, and "rows per second" every 10 seconds. results )) ) (info "Completed write") )