要件: テーブル全体をスキャンし、すべてのレコード、期間を更新する必要があります。
他の人が示唆したように、元のスキーマと同じスキーマを持つ一時テーブルを作成し、更新された値に挿入してから、元のテーブルを更新する代わりにテーブルの名前を変更する必要があります。
アイデアは次のようなものです。
ResultSet row = select * from old_table;
While row.next
do something to update values in this row
insert updated values in to a identical table (different name of course)
endWhile
ここでの質問は、Java JDBC を使用しており、ResultSet オブジェクトを処理する必要があるということです。「ResultSet row = select * from old_table」がメモリ不足の例外を生成するのを防ぐ方法はありますか?
潜在的な解決策はページングですが、それは ORDER BY と LIMIT を使用する必要があることを意味します。これは、300 万行のテーブルでは非常に遅くなる可能性があります。
FOWARD_ONLY | のようないくつかのフラグを指定するなど、ResultSet にトリックはありますか? NON-SCROLLABLEなど。または、Mysqlサーバーには、完全なテーブルスキャンを実行していることをmysqlが理解しているようなスマートなことを行うための構成があるので、レコードを順番に返しますが、一度にすべてではありません。
どんな提案でも大歓迎です
[更新] MySQL connector/J には という構成パラメーターがuseCursorFetch
あるようです。true に設定すると機能しstatement.setFetchSize(1000)
ます。これが究極の解決策かどうかはわかりません。