2017-06-01 24 views
0

我有一個合併成語句如下:合併成多個語句一次的Oracle SQL

private static final String UPSERT_STATEMENT = "MERGE INTO " + TABLE_NAME + " tbl1 " + 
    "USING (SELECT ? as KEY,? as DATA,? as LAST_MODIFIED_DATE FROM dual) tbl2 " + 
    "ON (tbl1.KEY= tbl2.KEY) " + 
    "WHEN MATCHED THEN UPDATE SET DATA = tbl2.DATA, LAST_MODIFIED_DATE = tbl2.LAST_MODIFIED_DATE " + 
    "WHEN NOT MATCHED THEN " + 
    "INSERT (DETAILS,KEY, DATA, CREATION_DATE, LAST_MODIFIED_DATE) " + 
    "VALUES (SEQ.NEXTVAL,tbl2.KEY, tbl2.DATA, tbl2.LAST_MODIFIED_DATE,tbl2.LAST_MODIFIED_DATE)"; 

這是執行方法:

public void mergeInto(final JavaRDD<Tuple2<Long, String>> rows) { 
    if (rows != null && !rows.isEmpty()) { 
     rows.foreachPartition((Iterator<Tuple2<Long, String>> iterator) -> { 

      JdbcTemplate jdbcTemplate = jdbcTemplateFactory.getJdbcTemplate(); 
      LobCreator lobCreator = new DefaultLobHandler().getLobCreator(); 

      while (iterator.hasNext()) { 
       Tuple2<Long, String> row = iterator.next(); 
       String details = row._2(); 
       Long key = row._1(); 

       java.sql.Date lastModifiedDate = Date.valueOf(LocalDate.now()); 
       Boolean isSuccess = jdbcTemplate.execute(UPSERT_STATEMENT, (PreparedStatementCallback<Boolean>) ps -> { 

        ps.setLong(1, key); 
        lobCreator.setBlobAsBytes(ps, 2, details.getBytes()); 
        ps.setObject(3, lastModifiedDate); 
        return ps.execute(); 
       }); 
       System.out.println(row + "_" + isSuccess); 

      } 
     }); 
    } 
} 

我需要UPSERT裏面這句話的多個如果可能的話,PLSQL,10K的大塊。

  1. 什麼是節省時間的有效方式:一次執行10K語句,或者如何在同一事務中執行10K語句?
  2. 我該如何改變支持它的方法?

謝謝,我

+0

表「hom」的用途和內容是什麼? –

+0

@ HAL9000編輯。應該是雙重 – userit1985

回答

1
  1. 最有效的方法將是一個批量加載您的數據到數據庫中。相比於逐一上傳(如您的示例),我預計性能增益至少爲1或2個數量級(「更大」的數據意味着通過批量插入獲得的更少)。

  2. 你可以使用的技術作爲this answer描述的第一批量插入的記錄到一個臨時表,然後執行使用臨時表中的 MERGE語句。

+0

我看到有一種批量插入方式使用batchUpdate,如https://stackoverflow.com/questions/9565481/how-to-do-multiple-inserts-in-database-using-spring-jdbc模板批次 每種方法的優點是什麼? – userit1985

+0

你必須測量/分析它。它們可能是相同的或非常不同的。但至少對於使用addBatch()的Oracle來說,每個批處理*(真正的批量加載)應該使用一個往返行程,而不是每行往返一次。 –