我试图使用Lambda函数从CSV文件到RDS (MySQL)插入近200,000条记录。完全插入所需的时间接近10分钟,这是非常令人担忧的。我想知道如何提高插入的速度。
我尝试过的技巧:
-
使用预处理语句进行批量插入,如下面的代码:
BufferedReader lineReader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));//inputStream is data from csv file try (PreparedStatement batchStatement = connection.prepareStatement(INSERT_QUERY)) {//connection is JDBC connection instance LOGGER.debug("Processing Insert"); Stream<String> lineStream = lineReader.lines().skip(1); List<String> collect = lineStream.collect(Collectors.toList()); for (String line : collect) { String[] data = line.split(",", -1); batchStatement.setString(1, data[0]); //remaining code of setting data batchStatement.addBatch(); batchStatement.executeBatch(); batchStatement.clearBatch(); } batchStatement.executeBatch(); connection.commit(); } catch(exception e){ //throw exception code }finally{ lineReader.close(); connection.close(); }
-
实现了rewritebatchedstatements=true在连接URL
请建议在这种情况下是否有任何可行的方法可以更快地将数据插入RDS (MySQL)
只按块执行批处理,比如一次执行100个,而不是像现在这样一次执行一个:
int rows = 0; // outside the loop
...
if((++rows % 100) == 0) {
batchStatement.executeBatch();
}
// Don't reset the batch as this will wipe the 99 previous rows:
//batchStatement.clearBatch();
另外:更改自动提交模式将改善批量更新,如果不使用addBatch或连接被重用,请记住在之后重置:
connection.setAutoCommit(false);
LOAD DATA INFILE
放到单独的表t1
中- 清理数据。也就是说,修复任何需要修改的东西,执行规范化等。
INSERT INTO real table (...) SELECT ... FROM t1
.
如果需要进一步讨论,请在SQL中提供表模式和步骤2所需的任何转换。此外,几行示例数据可能会有所帮助。