春季批处理 JdbcBatchItemWriter 插入在 MYSQL 中非常慢



我正在使用带有阅读器和写入器的块步骤。我正在从 Hive 读取 50000 块大小的数据,并以相同的 50000 次提交插入到 mysql 中。

@Bean
public JdbcBatchItemWriter<Identity> writer(DataSource mysqlDataSource) {
return new JdbcBatchItemWriterBuilder<Identity>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql(insertSql)
.dataSource(mysqlDataSource)
.build();
}

当我开始数据加载并插入 Mysql 时,它的提交速度非常慢,100000 条记录需要花费一个多小时才能加载,而带有 Gemfire 的同一个加载器在 30 分钟内加载了 500 万条记录。

似乎它一个接一个地插入而不是批量作为 Laoding 1500 然后 4000 然后....等等,有人遇到同样的问题吗?

由于您使用的是BeanPropertyItemSqlParameterSourceProvider,这将包括大量反射以在预准备语句中设置变量。这将增加时间。

如果速度是您的首要任务,请尝试实现您自己的ItemWriter,如下所示,并使用预准备语句批处理来执行更新。

@Component
public class CustomWriter implements ItemWriter<Identity> {
//your sql statement here
private static final String SQL = "INSERT INTO table_name (column1, column2, column3, ...) VALUES (?,?,?,?);";
@Autowired
private DataSource dataSource;
@Override
public void write(List<? extends Identity> list) throws Exception {
PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(SQL);
for (Identity identity : list) {
// Set the variables
preparedStatement.setInt(1, identity.getMxx());
preparedStatement.setString(2, identity.getMyx());
preparedStatement.setString(3, identity.getMxt());
preparedStatement.setInt(4, identity.getMxt());
// Add it to the batch
preparedStatement.addBatch();
}
int[] count = preparedStatement.executeBatch();
}
}

注意:这是一个粗略的代码。因此,异常处理和资源处理未正确完成。你可以做同样的事情。我认为这将大大提高您的写作速度。

尝试添加 ";useBulkCopyForBatchInsert=true"到您的连接 URL。

Connection con = DriverManager.getConnection(connectionUrl + ";useBulkCopyForBatchInsert=true")

来源 : https://learn.microsoft.com/en-us/sql/connect/jdbc/use-bulk-copy-api-batch-insert-operation?view=sql-server-ver15

最新更新