2

データベース テーブルから行をフェッチし、特定の条件に基づいて、他のテーブルに書き込むか、この行を特定の値で更新するバッチ ジョブを作成する必要があります。spring と jdbc を使用して結果セットをフェッチし、毎週実行するようにスケジュールされているスタンドアロンの Java プログラムを使用してレコードを繰り返し処理します。これが正しい方法ではないことは承知していますが、一時的な解決策として行う必要がありました。レコードが数百万に達すると、メモリ不足の例外が発生するため、これが最善のアプローチではないことはわかっています。

このような状況に対処するための最良の方法は何ですか?

スレッドを使用して、スレッドごとに 1000 レコードをフェッチし、それらを並行して処理しますか?

(また)

これを行うには、他のバッチメカニズムを使用します(スプリングバッチがあることは知っていますが、これを使用したことはありません)

(また)

他のアイデアはありますか?

4

4 に答える 4

7

100 万行をメモリに取り込んで操作できないことは既にご存じでしょう。

何らかの方法でそれらをチャンクする必要があります。

なぜそれらを中間層に持ち込むのですか? ストアド プロシージャを作成し、データベース サーバー上のデータを操作することを検討します。それを中間層に持ってきても、何も得られないようです。バッチ ジョブでストアド プロシージャを開始し、データベース サーバーでインプレースで計算を実行します。

于 2012-10-19T17:20:04.117 に答える
6

データベース テーブルから行をフェッチし、特定の条件に基づいて、他のテーブルに書き込むか、この行を特定の値で更新するバッチ ジョブ。

これは、データベース内で行うべきことのように思えます。たとえば、特定の行をフェッチし、特定の条件に基づいて更新するために、SQL にはUPDATE ... WHERE ...ステートメントがあります。別のテーブルに書き込むには、 を使用できますINSERT ... SELECT ...

これらはかなり複雑になるかもしれませんが、データベース内でこれを行うために全力を尽くすことをお勧めします。データを引き出してフィルター処理するのは非常に遅く、リレーショナル データベースを持つ目的に反するからです。

注: 最初に非本番システムでこれを試し、必要な制限を実装して、悪いときに本番テーブルをロックしないようにしてください。

于 2012-10-19T17:21:49.343 に答える
1

それは、レコードを何をどのように処理するかによって大きく異なります。

ただし、一般的に言えば、一度にすべてをメモリにロードするのではなく、適切なサイズのチャンクで処理する必要があります。

于 2012-10-19T17:20:14.057 に答える
0

一般的にブレンダンロングに同意します。ただし、ストアドプロシージャ内の「数百万」のデータセットのサブセットを選択しようとする可能性があります。それ以外の場合は、データベースのトランザクションログを吹き飛ばします。定期的に挿入または更新をコミットしていることを確認してください。

ストアドプロシージャでこれを実行したくない場合は、固定チャンクサイズで操作するレコードのキーをSpring Batchでロードするだけです(カーソル/ページングリーダーを使用)が、ストアドプロシージャに実行させる実際の作業。このようにして、Spring Batchのメリットとデータ操作におけるデータベースのパフォーマンスを活用しながら、中間層に渡されるデータを最小限に抑えることができます。

于 2012-10-19T18:42:07.267 に答える