2016-07-26 51 views
1

我試圖從java應用程序向數據庫中的各種表中插入大量的行。所以基本上我有一個單一的連接,我創建了多個Prepare語句。然後我通過設置準備語句的變量來準備幾個插入。最後,我執行每個Prepare語句作爲執行批處理並關閉語句。在Java Sql中執行批准的準備語句需要很長時間在最後一次迭代中

問題我面臨的是,我正在對上述過程進行迭代。

我有一個方法writeToDataBase(),它執行上述操作,並且此方法在循環內部調用。因此批量插入會發生很多次(每批次包含20個物體)。每次這種插入需要大約5到6秒才能在一次迭代中進行批量插入。但是在最後一次迭代中需要40秒的很長時間。

我認爲這可能是由於上一次迭代中寫入的數據所致。因此,我也改變了數據,使其輕量化,但即使如此,問題仍然存在。然後我試着禁用自動提交併手動提交。這也沒有幫助。

我也改變了迭代次數。例如,

在20個計數的循環中,第20個循環將花費大量時間。所以我改變它運行5次。但是這次第五回合運行時間更長。基本上最後一個循環需要很長時間來執行批處理。

檢查是否有內存泄漏,我也關閉語句是它的執行。但我無法理解爲什麼會發生這種情況。

下面提供了代碼片段。

for(ArrayList<DocumentObject> batch : documentBatches){ 
    DBWriter.writeToDataBase(batch); 
} 

public static synchronized boolean writeToDataBase(ArrayList<DocumentObject> batch)  { 
     try { 
    //Prepare Statements for insertion 
     String insertDocumentTableSQL = "INSERT INTO TEST.DOCUMENTS values (?,?,?,?,?,?,?,?);"; 
     PreparedStatement documentPreparedStatement = connection.prepareStatement(insertDocumentTableSQL); 
     String insertSentencesTableSQL = "INSERT INTO TEST.SENTENCES values (?,?,?,?,?,?);"; 
     PreparedStatement sentencesPreparedStatement = connection.prepareStatement(insertSentencesTableSQL); 
    //Preparing multiple inserts to the prepare statements 
    for(DocumentObject docObj : batch){ 
    documentPreparedStatement = prepareInsertsToDocumentsTable(docObj,documentPreparedStatement);   //sets the '?' in the query with actual values and adds it to the batch 
    sentencesPreparedStatement = prepareInsertsToSentencesTable(headlineSRLDocument, sectionId,sentencesPreparedStatement); 
     } 
    //execute the preparestatements 
     connection.setAutoCommit(false); 
    long start = System.currentTimeMillis(); 
     documentPreparedStatement.executeBatch(); 
     sentencesPreparedStatement.executeBatch(); 
     connection.commit(); 
     documentPreparedStatement.close(); 
     sentencesPreparedStatement.close(); 
    System.out.println("time taken for Execute Statements: "+(System.currentTimeMillis()-start)/1000+" seconds"); 
    return true; 
    } 

下面是控制檯輸出,我有跟蹤每次迭代所需的時間。採取

時間執行語句:3秒

時間採取執行語句:4秒

時間採取執行語句:4秒

時間採取執行語句:4秒

執行時間:5秒

採取執行語句時間:5秒

時間採取執行語句:9秒

時間採取執行語句:10秒

時間採取執行語句:6秒

採取執行語句時間:47秒 < ------最後一次迭代花費更多的時間

+0

嘗試在每次調用中添加這些時序語句以確定哪些函數需要更多時間?順便說一句,這是什麼數據庫? –

+0

是目前發生的垃圾收集活動嗎? –

+0

嗨Sameer,我正在使用SAP HANA數據庫。我發現.executeBatch()語句需要更多時間。但是在其他迭代中,它不會消耗太多時間。我不確定垃圾收集活動。 –

回答

1

我找到了答案。這是基本上發生的,因爲最後一個循環與其他循環相比準備了更多的語句並將其添加到批處理中。

我檢查了這一點,有一個一致的數據集,我知道將爲每個循環準備的語句數並添加到批處理中。之前的語句是動態生成和添加的,因此我不知道循環中正在執行的語句的數量。因此,像我推測的那樣,preparedStatement.executeBatch()或數據庫沒有問題。

謝謝你幫助我。