java - 在上次迭代期间花费很长时间在 Java Sql 中执行批量准备语句

标签 java sql database prepared-statement hana

我正在尝试从 Java 应用程序将大量行插入到数据库中的各种表中。所以基本上我有一个连接,我用它创建多个 Prepare 语句。然后我通过设置准备语句的变量来准备几个插入。最后,我将每个 Prepare 语句作为 execute Batch 执行并关闭语句。

我面临的问题是,我正在对上述过程进行迭代。

我有一个方法 writeToDataBase(),它执行上述操作,这个方法在循环内调用。因此批量插入发生了很多次。(每批包含 20 个对象)。每次插入需要大约 5 到 6 秒才能在一次迭代中进行批量插入。但在最后一次迭代中需要很长时间,大约 40 秒。

我认为这是由于上一次迭代中写入的数据所致。因此,我也更改了数据以使其轻量级,但即便如此问题仍然存在。然后我尝试禁用自动提交并手动提交。这也没有帮助。

我还更改了迭代次数。例如,

在 20 个计数的循环中,第 20 个循环会花费很多时间。所以我将其更改为运行 5 次。但是这次第 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;  
    }  

下面是控制台输出,我必须跟踪每次迭代所用的时间。

time taken for Execute Statements: 3 seconds

time taken for Execute Statements: 4 seconds

time taken for Execute Statements: 4 seconds

time taken for Execute Statements: 4 seconds

time taken for Execute Statements: 5 seconds

time taken for Execute Statements: 5 seconds

time taken for Execute Statements: 9 seconds

time taken for Execute Statements: 10 seconds

time taken for Execute Statements: 6 seconds

time taken for Execute Statements: 47 seconds <------ last iteration taking more time

最佳答案

我找到了答案。与其他循环相比,这基本上是因为最后一个循环正在准备更多语句并将其添加到批处理中。

我通过有一个一致的数据集检查了这一点,我知道将为每个循环准备并添加到批处理中的语句的数量。以前,语句是动态生成和添加的,因此我对循环中执行的语句数量一无所知。因此,正如我推测的那样,preparedStatement.executeBatch() 或数据库没有问题。

谢谢你帮助我。

关于java - 在上次迭代期间花费很长时间在 Java Sql 中执行批量准备语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38580824/

相关文章:

java - Jsoup Element.val() 解码编码的 html 内容

php - 我可以在执行 UPDATE 时从 mySQL 数据库检索变量吗?

mysql - 基于文本的主索引有哪些缺点

python - 为什么在 Django 中,uniques 不成立?

java - 以增量方式存储文件

java - 如何使用类参数分解 dao

mysql - 如何使用 SQL 合并和计算具有不同值的多行

android - 我怎样才能让玩家更难破解游戏关卡数据?

database - SQLite 中的 "if, then, else"

java - 使 JTextField 仅接受一位数字