Javaプログラムを作成して、テーブルの行をクリーンアップしてマージします。テーブルが大きく、約50万行あり、現在のソリューションの実行が非常に遅いです。最初にしたいこと行うことは、単にテーブルのすべての行を表すオブジェクトのメモリ内配列を取得することです。
これは長い道のりを歩んでいます。実際には、1000から2000の2番目の増分を超えていません。クエリが完了するまでに永遠にかかります(ただし、同じことをMySQLブラウザから直接実行すると、かなり高速です)。 JDBCを直接使用してからしばらく経ちました。より速い代替手段はありますか?
まず、メモリ内のテーブル全体が必要ですか? (可能であれば)更新/マージ/その他の行を選択することを検討する必要があります。テーブル全体が本当に必要な場合は、スクロール可能なResultSetの使用を検討してください。このように作成できます。
// make sure autocommit is off (postgres)
con.setAutoCommit(false);
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, //or ResultSet.TYPE_FORWARD_ONLY
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery("select * from ...");
'absolute'および 'relative'メソッドを使用して、任意の行に移動できます。
おそらく最適ではありませんが、ソリューションは1回限りのデータベースクリーンアップルーチンでは問題ないようです。このようなクエリを実行して結果を取得するのにそれほど長くはかからないはずです(1秒なので、数秒で問題ないでしょう)。考えられる問題-
ネットワーク(または少なくともmysqlへの接続)は非常に遅いですか?その場合は、mysqlボックスでローカルにプロセスを実行するか、またはより適切な接続を試すことができます。
それを引き起こしているテーブル構造に何かありますか?行ごとに10kのデータを引き下げますか? 200フィールド?インデックス付けされていない行に基づいて取得するID値を計算しますか?データをプルする、よりdbに適した方法を見つけることを試みることができます(たとえば、必要な列だけ、dbの集計値など)
2番目のインクリメントを実行していない場合、何かが本当に間違っている-効率的であるかどうかにかかわらず、実行中のJVMのメモリに2000行または20,000行をダンプする問題はないはずです。多分あなたはデータを冗長に、または非常に非効率的に保存していますか?
私を助けたのはStatement.setFetchSize(Integer.MIN_VALUE)
です。私はこのアイデアを Jasonのブログ から得ました。これにより、実行時間が半分以上削減されました。消費されるメモリが劇的に減少しました(一度に1行しか読み込まれないため)。
ただし、このトリックはPreparedStatement
では機能しません。