入力セット:50000を超えるエントリを含む数千(> 10000)のcsvファイル。 出力:これらのデータをmysql dbに格納します。単一トランザクションでmysqlに50000+レコードを格納するベストプラクティス
アプローチ: 各ファイルを読み込んでデータベースに格納します。以下は同じもののコードスニペットです。この方法がOKかどうかをお勧めします。
PreparedStatement pstmt2 = null;
try
{
pstmt1 = con.prepareStatement(sqlQuery);
result = pstmt1.executeUpdate();
con.setAutoCommit(false);
sqlQuery = "insert into "
+ tableName
+ " (x,y,z,a,b,c) values(?,?,?,?,?,?)";
pstmt2 = con.prepareStatement(sqlQuery);
Path file = Paths.get(filename);
lines = Files.lines(file, StandardCharsets.UTF_8);
final int batchsz = 5000;
for (String line : (Iterable<String>) lines::iterator) {
pstmt2.setString(1, "somevalue");
pstmt2.setString(2, "somevalue");
pstmt2.setString(3, "somevalue");
pstmt2.setString(4, "somevalue");
pstmt2.setString(5, "somevalue");
pstmt2.setString(6, "somevalue");
pstmt2.addBatch();
if (++linecnt % batchsz == 0) {
pstmt2.executeBatch();
}
}
int batchResult[] = pstmt2.executeBatch();
pstmt2.close();
con.commit();
} catch (BatchUpdateException e) {
log.error(Utility.dumpExceptionMessage(e));
} catch (IOException ioe) {
log.error(Utility.dumpExceptionMessage(ioe));
} catch (SQLException e) {
log.error(Utility.dumpExceptionMessage(e));
} finally {
lines.close();
try {
pstmt1.close();
pstmt2.close();
} catch (SQLException e) {
Utility.dumpExceptionMessage(e);
}
}
大量のエクスポートをダンプまたはインポートしてすべてを挿入しようとしました。 –
用語を明確にしますか? SQLワールドダンプでは、一連のSQLクエリ、CSV、または所有者の形式のいずれかとして、データベースからエクスポートされたデータを意味します。ダンプまたはデータベースからデータを取得することは、インポートまたはロードと呼ばれます。あなたの質問を明確にすることができたら... – e4c5
私は最近、同様の問題を処理しました。私の場合、データは600,000+です。私の解決策は、マルチスレッドとブロックキューを使用してデータをインポートすることです。ただし、マルチスレッドではパフォーマンスが実際に向上するわけではなく、応答時間が短縮されるだけです。本当に速くしたい場合は、並列ソリューションを検討してください。しかし、50,000は並列化するには小さすぎますが、複雑さは利益をはるかに上回ります。したがって、バルク挿入のシングルスレッドを貼っておくことをお勧めします。 –