Spring Batch SQL Merge需要太长时间

时间:2016-09-16 16:04:50

标签: sql-server spring oracle spring-boot spring-batch

我正在尝试将数据从Oracle迁移到SQLServer数据库。我目前正在使用JDBCCursorItemReader来读取Oracle数据,然后使用JDBCBatchItemWriter将数据写入SQLserver。

我的问题是,这花了太长时间。对于大约200,000行的表,它需要将近一个小时(我必须运行其中四个查询,每个查询大约200K行)。

@Bean
public JdbcCursorItemReader<DataPOJO> dataReader() throws Exception, ParseException, UnexpectedInputException {
        final JdbcCursorItemReader<DataPOJO> dataReader= new JdbcCursorItemReader<>();

        dataReader.setDataSource(oracleDataSource);
        dataReader.setSql(Constants.DATA_QUERY);
        dataReader.setRowMapper(new BeanPropertyRowMapper<DataPOJO>(DataPOJO.class));
        return dataReader;
    }

@Bean
    public JdbcBatchItemWriter<DataPOJO> dataWriter() throws UnexpectedInputException, ParseException, Exception {

        JdbcBatchItemWriter<DataPOJO> dataWriter = new JdbcBatchItemWriter<>();
        dataWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<DataPOJO>());
        dataWriter.setSql(Constants.DATA_MERGE);
        dataWriter.setDataSource(mssDataSource);
        return dataWriter;
    }

有没有人提出改善这类工作表现的建议?

2 个答案:

答案 0 :(得分:0)

  

有没有人提出改善这类工作表现的建议?

我会以这种方式接近..

1.查看我正在运行的进程的等待统计信息

select * from sys.dm_exec_requests where session_id=<< your session id>>

要识别您的sessionid,您可以检查sys.processes

select spid,waittime,lastwaittype,status
hostname,     --below three columns help you identify your query/spid,
 program_name,--- you can replace spid in above query to get live status
nt_username
 from sys.sysprocesses

2.基于等待类型的故障排除..

答案 1 :(得分:0)

我首先将您的记录插入源表(个人而言,我使用临时表),然后利用MERGE命令从该源&#34;源&#34;中推送记录。表格进入你的&#34;目标&#34;表

一些关键性能问题:

  • 确保您匹配目标表上的索引键
  • 假设您要更新MATCHED行,请不要将索引列更新为UPDATE语句的一部分
  • 将提交间隔设置得相当高。您的数据库应该能够合并1000行而不会出汗。过于频繁地提交会增加很多开销。

现在使用Spring Batch完成此任务,您可能需要一个复合ItemWriter(一个开箱即用的框架)。委托编写者1将是您已经使用的JdbcBatchItemWriter并将插入该源表。委托编写者2将是自定义的,只需执行您的MERGE命令。