2017-06-14 6 views
0

私は1つのMySQLインスタンスから多数のレコードをRDS内で2つずつ移動しようとしています。彼らは異なるVPCと異なるAWSアカウントにあるので、私のためにコピーを行うデータパイプラインを作成することはできません。複数の挿入を一括して実行するには、mysql jdbcドライバクラスが認識していますか?

私は、インポート・データベースおよびエクスポート・データベースの両方に接続しない迅速なJavaプログラムを書いた次

  1. クエリSELECT MAX(primary_key) FROM table
  2. とtable.primary_keyで最高のインポートデータベースSELECT * FROM table WHERE(primary_key > max_from_import) LIMIT 1000000
  3. でエクスポートテーブルからの結果セットは、インポート接続からPreparedStatementオブジェクトを作成し、結果セットとs上INSERT INTO table (col1....coln) VALUES (?....n?)
  4. 反復するためのqueryStringを設定しますPreparedStatementオブジェクトを実行し、そのパラメータをクリアしてから次の結果に移動します。私は時間をインポートされて周り100000レコードを表示することができるよ、私はthis questionからの挿入を最適化する方法は、新しいクエリを毎回作成するために、より多くのデータを追加しないことをことを知っているこの方法で

それぞれのインサートで。すなわち

INSERT INTO table (col1...coln) VALUES (val1...valn), (val1...valn)....(val1...valn); 

JDBCドライバは、これを行うには知っている、または私は、インサートの実行時間を改善するために、私の終わりに作ることができ、最適化のいくつかの並べ替えがありますか?

更新: 追加と実行のバッチを使用して自動コミットを削除することをお勧めします。オートコミットを削除するとわずかな改善(10%)が見られ、バッチを実行すると個々のインサートの実行時間が50%未満になりました。

+0

MyISAMテーブルを使用していない限り、トランザクション内に挿入ステートメントをラップし、オートコミットをオフにしたり、 100または1000の挿入ごとにコミットを発行します。正確な詳細は私には分かりますが、質問には 'rewriteBatchedStatements'接続オプションがあります。ここにはhttps://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration- properties.html – nos

+0

おそらく 'Statement#executeBatch()'が役に立ちます。 –

+0

@CBredlow - あなたは自分の方法で挿入をスピードアップできますか? –

答えて

1

バッチインサートを使用する必要があります。内部的にConnector/J(MySQL JDBCドライバ)はバッチ挿入を複数の値のinsert文に書き換えることができます。

(これはデフォルトのConnector/Jの動作です。あなたは)書類を作成し、サーバー側を有効にするには、JDBCのURLに

を オプションuseServerPrepStmts=trueを追加することができ、コードは次のようになります。

try(PreparedStatement stmt = connection.prepareStatement(sql)) { 
    for(value : valueList) { 
     stmt.clearParameters();  
     stmt.setParameter(1, value); 
     stmt.addBatch(); 
    } 
    stmt.executeBatch(); 
} 

上記のコードは、複数値の挿入を生成します。

INSERT tablename(field) VALUES(value1), (value2), (value3) ... 
1

まず、接続先データベースへのJDBC接続を作成し、自動コミットプロパティをfalseにします。その後

ループで次

読むNを行い、ソース・データベースからの行の数(例えば1000)宛先データベースにそれを書き込みます。

いくつかの挿入後に接続先データベース接続をコミットします。より多くのアイデアを得るために

サンプルコードはINSERT INTO table (col1...coln) VALUES (val1...valn), (val1...valn)....(val1...valn);形式で文字列を与える必要があります

Connection sourceCon = getSourceDbConnction(); 
Connection destCon = getDestinationDbConnction(); 
destCon.setAutoCommit(false); 
int i=0; 
String query; 
while((query=getInsertQuery()!=null) 
{   
    statement.executeUpdate(query); 
    i++; 
    if(i%10 == 0) 
    { 
     destCon.commit(); 
     i=0; 
    } 
} 
destCon.commit(); 

getInsertQuery機能の下に与えられています。 また、すべてのテーブルが処理される場合は、nullが返されます。

プリペアドステートメントを使用している場合は、addBatchexecuteBatchの機能を使用できます。ループ内には、addBatch機能を使用して値を追加します。いくつかの挿入後にexecuteBatchを呼び出します。

+0

@CBredlow - 大きな差を見るために、より高い値でi%10の文でその10を変更することができます。 –

+0

@CBredlow - 1つの挿入ステートメントに挿入する行の数はいくつですか? –

+0

@CBredlow - Prepared Statementsを使用している場合は、コード内でaddBatchおよびexecuteBatch関数を使用してください。 –

関連する問題