zoukankan      html  css  js  c++  java
  • JDBC更新10W级以上数据性能优化

    随笔缘由:

    系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试。 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录。 一番小小研究,觉得总结一下可能有些意义。

     

    总结内容如下:

    1:这是我出现问题的代码,插入10W条数据,10W次数据进行一次批处理,发现只能插入24464多条数据,程序也没有报错。

    Connection con = (Connection) DriverManager.getConnection(url,user,password); 
     con.setAutoCommit(false); 
     Long startTime = System.currentTimeMillis(); 
     PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
     for (int i = 0; i < list.size(); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString(1, kivResponseBean.getK()); 
         pst.setString(2, kivResponseBean.getI()); 
         pst.setInt(3, kivResponseBean.getV()); 
         pst.setInt(4, kivResponseBean.getD()); 
         pst.setString(5, kivResponseBean.getM()); 
         pst.setString(6, kivResponseBean.getR()); 
         pst.addBatch();    
    }               
     pst.executeBatch();
     con.commit(); 
     Long endTime = System.currentTimeMillis(); 
     System.out.println("用时:" + (endTime - startTime)); 

    2:在不使用批更新时,具体做法就是 不添加这句代码 con.setAutoCommit(false); 并且每次为SQL指定参数后就执行 pst.executeUpdate(); 提交数据;结果10W条记录插入成功,但是使用了 35833ms的时间消耗。

    Class.forName("oracle.jdbc.driver.OracleDriver"); 
     Connection con = (Connection) DriverManager.getConnection(url,user,password); 
     Long startTime = System.currentTimeMillis(); 
     PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
     for (int i = 0; i < list.size(); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString(1, kivResponseBean.getK()); 
         pst.setString(2, kivResponseBean.getI()); 
         pst.setInt(3, kivResponseBean.getV()); 
         pst.setInt(4, kivResponseBean.getD()); 
         pst.setString(5, kivResponseBean.getM()); 
         pst.setString(6, kivResponseBean.getR()); 
         pst.executeUpdate();
    }               
     Long endTime = System.currentTimeMillis(); 
     System.out.println("用时:" + (endTime - startTime));

     

    3:使用批更新,并且制定没10000次提交一次更新,此时 使用时间 2980 ms ,10w条数据也批量添加成功,oracle对每次执行的批更新有限制,我在11g的环境下测试 在2W4K多,网上有朋友说在10g下 每次提交1W多数据就会报错。

    Class.forName("oracle.jdbc.driver.OracleDriver"); 
    Connection con = (Connection) DriverManager.getConnection(url,user,password); 
    con.setAutoCommit(false); 
    Long startTime = System.currentTimeMillis(); 
    PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
    int batchCount=list.size()/batchSize+1;
    for(int batch=0;batch<batchCount;batch++) {
        for (int i = batch*batchSize; (i <(batch+1)*batchSize)&&(i<list.size()); i++) { 
            KIVResponseBean kivResponseBean=list.get(i);  
            pst.setString(1, kivResponseBean.getK()); 
            pst.setString(2, kivResponseBean.getI()); 
            pst.setInt(3, kivResponseBean.getV()); 
            pst.setInt(4, kivResponseBean.getD()); 
            pst.setString(5, kivResponseBean.getM()); 
            pst.setString(6, kivResponseBean.getR()); 
            pst.addBatch();    
       }               
        pst.executeBatch();
        con.commit(); 
        pst.clearBatch();
    }
    Long endTime = System.currentTimeMillis(); 
    System.out.println("用时:" + (endTime - startTime)); 

    随笔缘由:

    系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试。 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录。 一番小小研究,觉得总结一下可能有些意义。

     

    总结内容如下:

    1:这是我出现问题的代码,插入10W条数据,10W次数据进行一次批处理,发现只能插入24464多条数据,程序也没有报错。

    Connection con = (Connection) DriverManager.getConnection(url,user,password); 
     con.setAutoCommit(false); 
     Long startTime = System.currentTimeMillis(); 
     PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
     for (int i = 0; i < list.size(); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString(1, kivResponseBean.getK()); 
         pst.setString(2, kivResponseBean.getI()); 
         pst.setInt(3, kivResponseBean.getV()); 
         pst.setInt(4, kivResponseBean.getD()); 
         pst.setString(5, kivResponseBean.getM()); 
         pst.setString(6, kivResponseBean.getR()); 
         pst.addBatch();    
    }               
     pst.executeBatch();
     con.commit(); 
     Long endTime = System.currentTimeMillis(); 
     System.out.println("用时:" + (endTime - startTime)); 

    2:在不使用批更新时,具体做法就是 不添加这句代码 con.setAutoCommit(false); 并且每次为SQL指定参数后就执行 pst.executeUpdate(); 提交数据;结果10W条记录插入成功,但是使用了 35833ms的时间消耗。

    Class.forName("oracle.jdbc.driver.OracleDriver"); 
     Connection con = (Connection) DriverManager.getConnection(url,user,password); 
     Long startTime = System.currentTimeMillis(); 
     PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
     for (int i = 0; i < list.size(); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString(1, kivResponseBean.getK()); 
         pst.setString(2, kivResponseBean.getI()); 
         pst.setInt(3, kivResponseBean.getV()); 
         pst.setInt(4, kivResponseBean.getD()); 
         pst.setString(5, kivResponseBean.getM()); 
         pst.setString(6, kivResponseBean.getR()); 
         pst.executeUpdate();
    }               
     Long endTime = System.currentTimeMillis(); 
     System.out.println("用时:" + (endTime - startTime));

     

    3:使用批更新,并且制定没10000次提交一次更新,此时 使用时间 2980 ms ,10w条数据也批量添加成功,oracle对每次执行的批更新有限制,我在11g的环境下测试 在2W4K多,网上有朋友说在10g下 每次提交1W多数据就会报错。

    Class.forName("oracle.jdbc.driver.OracleDriver"); 
    Connection con = (Connection) DriverManager.getConnection(url,user,password); 
    con.setAutoCommit(false); 
    Long startTime = System.currentTimeMillis(); 
    PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
    int batchCount=list.size()/batchSize+1;
    for(int batch=0;batch<batchCount;batch++) {
        for (int i = batch*batchSize; (i <(batch+1)*batchSize)&&(i<list.size()); i++) { 
            KIVResponseBean kivResponseBean=list.get(i);  
            pst.setString(1, kivResponseBean.getK()); 
            pst.setString(2, kivResponseBean.getI()); 
            pst.setInt(3, kivResponseBean.getV()); 
            pst.setInt(4, kivResponseBean.getD()); 
            pst.setString(5, kivResponseBean.getM()); 
            pst.setString(6, kivResponseBean.getR()); 
            pst.addBatch();    
       }               
        pst.executeBatch();
        con.commit(); 
        pst.clearBatch();
    }
    Long endTime = System.currentTimeMillis(); 
    System.out.println("用时:" + (endTime - startTime)); 
  • 相关阅读:
    Python数据库查询中文乱码的问题处理
    Unable to update the EntitySet 'Relationship' because it has a DefiningQuery and no <DeleteFunction> element exists in the <ModificationFunctionMapping> element to support the current operation
    Entity Framework入门教程:通过Entity Framework实现数据库数据的增、删、改
    推荐几款.NET客户端开源报表图
    Entity Framework入门教程:SQLite数据源访问
    Entity Framework入门教程: Entity Framework支持的查询方式
    无法为具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6”
    Entity Framework入门教程:创建实体数据模型
    WPF's Style BasedOn
    在 WPF 中使用 Path 路径
  • 原文地址:https://www.cnblogs.com/firstdream/p/7689307.html
Copyright © 2011-2022 走看看