【问题标题】:Spring Batch SQL Merge Takes Too LongSpring Batch SQL 合并耗时过长
【发布时间】:2017-01-24 22:31:50
【问题描述】:

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

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

@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;
    }

有没有人有任何提高这类工作表现的技巧?

【问题讨论】:

  • 这看起来绝对像一个数据库问题。如果直接在 sql/db 浏览器中运行 Select-Query 需要多长时间才能返回?此外,您是否将自动提交设置为 false?您的步骤中的 commitSize 是多少?通常,您应该能够每秒读取和写入数千个条目。

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


【解决方案1】:

有没有人有任何提高这类工作表现的技巧?

我会这样接近..

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.根据等待类型排错..

【讨论】:

    【解决方案2】:

    我会首先将您的记录插入到源表中(就我个人而言,我会使用临时表),然后利用 MERGE 命令将该“源”表中的记录推送到“目标”表中。

    几个关键的性能问题:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-15
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 2015-08-19
      相关资源
      最近更新 更多