2011-12-18 22 views
4

私は作業中のアプリケーションがデフォルトのフェッチサイズを使用していることに気づきました。問題は、大部分の場合、ユーザーが大量のデータ(数千から数十万に及ぶ)をフェッチし、デフォルトの10が実際には大きなボトルネックになっていることです。JDBC/Hibernate Fetchサイズとメモリの問題

したがって、ここでの明白な結論は、フェッチサイズを大きくすることです。最初は、デフォルト値を100に設定し、いくつかのクエリで1000に設定することを考えていました。しかし、ネット上では、メモリの問題を防ぐためにデフォルト値が小さすぎる(つまり、JVMヒープがそれほど多くのデータを処理できない場合)、私はそれについて心配すべきでしょうか?

これ以上の説明はありません。結果セットをフェッチしている間にフェッチサイズが大きくなるとオーバーヘッドが増えることを意味しますか?あるいは、デフォルトでは10レコードをフェッチしてGCをGCして別の10などをフェッチすることができます(一方で10000を一度にフェッチするとOutOfMemory例外が発生します)。このような場合は、とにかくメモリ内のすべてのレコードが必要なので、私は本当に気にしません。前者の場合(結果セットが大きければメモリのオーバーヘッドが大きくなります)、まずテストをロードする必要があります。

答えて

4

フェッチサイズも大きく設定すると、となり、OutOfMemoryErrorになります。

これらのすべてが必要な事実は、とにかくのレコードはおそらく正当ではありません。より多くの機会にエンティティが返されました。ResultSet s ...フェッチサイズを10000に設定すると、JDBCクラスで表される10000レコードがヒープされます。もちろん、あなたはこれらをあなたのアプリケーションを通して渡すことはありません。最初にそれらをお気に入りのビジネスロジックエンティティに変換し、ビジネスロジック実行者に渡します。この方法では、JDBCが次のフェッチ・バルクをフェッチするとすぐに、最初のフェッチ・バルクからのレコードをGCで使用できます。

通常、この変換は前述のメモリの脅威のため、一度に少しずつ実行されます。あなたは絶対的に正しい

一つのことは、しかし:あなたべき明確に定義された要件を微調整する前にとパフォーマンスのためテスト。

+0

実際にフェッチサイズを10からバンプすると、100と言うことができます。私はヒープ上に90以上のjdbcオブジェクトしか取得できません。コール直後にGCedされます(ヒープに最大100個のjdbcオブジェクトがあります) ? –

+0

はい、反復された 'ResultSet'に属する100個のjdbcオブジェクトです。少なくとも、合理的な実装と見なされます... JDBC仕様AFAIKでは強制されません。 – yair

1

ここで明らかな結論は、フェッチサイズを大きくすることです。

おそらく、「ユーザーが戻すオブジェクトの数を減らすことができるかどうかを見てみましょう。 Googleが結果を返すとき、あなたは25〜50のバッチでそれを行い、あなたが有用であると考えられる最大の可能性でソートします。ユーザーが何千ものオブジェクトを戻している場合は、おそらくそれを減らす方法を考える必要があります。データベースはより多くの作業を行うことができますか?それらのオブジェクトのいくつかを削除するために書き込むことができる他の操作がありますか?オブジェクト自体がよりスマートになりますか?

+0

これは私の「第2の数字」でしたが、大きな「ビジネス」知識を持つ同僚の一部に相談したところ、結論は単純でした。私たちはすべてのデータを記憶に入れる必要があります。だから残念ながら私は数字を切り捨てる方法は見当たりません。 –

+0

次に、より多くのメモリが必要です。また、32ビットのJVMを実行している場合、2GBのJVMヒープサイズ制限に対して実行します。 64ビットにしてより大きなヒープを割り当てることを除いて、あなたはそれについて何もできません。 – duffymo

+0

うん、私はそれを知っている:)私の全体的な質問は、 "とにかくメモリにXXXkオブジェクトを持っていて、フェッチサイズを10から100/1000に増やすことは、このような場合には大きな問題になるだろう"何が起こるかを見るためにいくつかのまともな負荷テストを要求する必要があります。 –