2016-09-16 49 views
2

我正在嘗試將數據從Oracle遷移到SQLServer數據庫。我目前使用JDBCCursorItemReader讀取Oracle數據,然後使用JDBCBatchItemWriter將數據寫入SQLserver。彈簧批量SQL合併時間太長

我的問題是,這是服用了太多的時間。對於大約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; 
    } 

有沒有人有任何提示,以改善這些類型的工作表現?

+0

這看起來絕對像一個數據庫問題。如果直接在sql/db瀏覽器中運行它,Select-Query將返回多長時間?此外,你是否將自動提交設置爲false?你的步驟的提交大小是多少?通常,您應該能夠每秒讀取和寫入幾千條條目。 –

回答

0

有沒有人有關於這些類型的工作提高性能的任何提示?

我會以這種方式接近..

1.See該進程的等待統計數據我運行

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

要識別您的會話ID,您可以檢查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.基於等待類型的排錯..

0

我會先將您的記錄插入源表(親自使用臨時表),然後利用MERGE命令將記錄從「源」表中推送到「目標」表中。

幾個關鍵性能的擔憂:

  • 確保你對你的目標表
  • 索引鍵匹配的假設要更新匹配的行,不更新索引列(S)的一部分您的UPDATE聲明
  • 設置您的提交間隔體面高。你的數據庫應該能夠合併1000行而不會冒汗。頻繁提交會增加大量開銷。

現在要用Spring Batch來完成這個任務,您可能需要一個複合ItemWriter(其中一個來自框架)。代表作家1將是您已經使用的JdbcBatchItemWriter,並將插入到該源表中。代表作家2將是自定義的,只需執行MERGE命令。