2009-10-01 14 views
8

の外に与える私は大きな結果を返すPostgreSQLのクエリを実行しようとしています:JDBC +大PostgreSQLのクエリは、メモリ

connection.setAutoCommit(false); 
st = connection.createStatement(
    ResultSet.CONCUR_READ_ONLY, 
    ResultSet.TYPE_FORWARD_ONLY 
); 
st.setFetchSize(100); 
logMemory(); 
System.out.println("start query "); 
rs = st.executeQuery(queryString); 
System.out.println("done query "); 
logMemory(); 

をしかし、これは多くのメモリを使用する:

Free memory; 4094347680 (= 3905 mb). 
start query 
done query 
Free memory; 2051038576 (= 1956 mb). 

( Runtime.getRuntime()。freeMemory())

これまでのところ動作しますが、データベースはもっと大きくなるでしょう。私は記憶の中で結果全体を必要とすることはありません。私はちょうど各行を処理し、ディスクに結果を書いて、次の行に行く必要があります。

私は 'setFetchSize'はほんのヒントだと知っていますが、postgresql/jdbcがそれを無視するならば、それは奇妙なものです。

これを回避する方法はありますか?これまでの私の唯一のアイデアは、クエリの結果をディスクにストリームしてJavaからファイルを解析するバッチスクリプトを作成することです...

+0

好奇心が強い、あなたが実行している最大ヒープサイズは?または、デフォルトを使用していますか? –

+1

-Xmx4096M -Xms4096M、それはVistaの8GBマシンです。 – kresjer

答えて

7

これは、私が見たJDBCを使った中で最も厄介なバグの1つです。 (あなたはカーソルのために他の基準を満たしてきたように)あなたはたぶん単に

st = connection.createStatement(); 

も同様に動作します

st = connection.createStatement(
    ResultSet.TYPE_FORWARD_ONLY, 
    ResultSet.CONCUR_READ_ONLY 
); 

st = connection.createStatement(
    ResultSet.CONCUR_READ_ONLY, 
    ResultSet.TYPE_FORWARD_ONLY 
); 

を変更する必要があります。

+0

バグは何ですか?それは本当のメモリリークですか、それとも何か他のことが起こっていますか?それはポストグルだけだと思いますか? – rogerdpack

+0

@rogerdpack OPは、 'createStatement'のメソッドパラメータを変更しました。どちらのパラメータも 'int'ですが、いくつかの異なることを意味します。したがって、JDBCの実装にはバグはありません。 –

9

は、結果セットが実際にカーソル。あなたはあなたのコードで知られているすべてのものにヒットしたようですが、あなたはそのステートメントを指定していないので、セミコロンと一緒にいくつかつながっている可能性があります。 V3プロトコル(バージョン7.4以降)を使用する必要があります。これらのことはすべてあなたの場合に当てはまりますか?

+0

ええ、私はすべてのガイドラインをオン/オフに切り替えようとしました。この文は単純に です.hh.data、hh.customer_IDを選択してください。 from dataTable hh hh.customer_ID = PH.customer_IDにお客様PHに参加してください。 とそれはpostgresql 8.3です。私はpostgresql-8.3-603.jdbc4.jarを使用しています。 – kresjer

+0

私は困惑しています。次のベストステップは、PostgreSQLに焦点を当てたグループに投稿することです。接続にカーソルを使用させる/引き起こす可能性がある他の明白でないものがいくつかあります。私はオープンソースに関する素晴らしいソースであるJDBCのソースコードをオープンして、あなたのシナリオで何が起こっているのか見ていきます。 – Yishai

+1

お返事ありがとうございました。あなたが引用したページに 'conn.setAutoCommit(false)'の必要条件が見つかるまで、私はこの問題を一日中苦労していました。 – jutky

関連する問題