Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring jdbcTemplate vs PreparedStatement。性能差异_Java_Sql_Spring - Fatal编程技术网

Java Spring jdbcTemplate vs PreparedStatement。性能差异

Java Spring jdbcTemplate vs PreparedStatement。性能差异,java,sql,spring,Java,Sql,Spring,我正在使用Oracle11g。我的数据库中有3个表(A、B、C) 我有一段代码,它执行三次插入:首先插入a和C,然后插入B。这段代码执行了很多次(200000),并在每个表中执行200000插入操作 我有两种插入方式: jdbc准备的声明: DataSource ds = jdbcTemplate.getDataSource(); try (Connection connection = ds.getConnection(); PreparedStatement statement

我正在使用Oracle11g。我的数据库中有3个表(
A、B、C
) 我有一段代码,它执行三次插入:首先插入
a
C
,然后插入
B
。这段代码执行了很多次(
200000
),并在每个表中执行
200000
插入操作

我有两种插入方式:

  • jdbc准备的声明:

    DataSource ds = jdbcTemplate.getDataSource();
    
    try (Connection connection = ds.getConnection();
         PreparedStatement statement = connection.prepareStatement(sql1);
         PreparedStatement statement2 = connection.prepareStatement(sql2);
         PreparedStatement statement3 = connection.prepareStatement(sql3);) {
    
         connection.setAutoCommit(false);
         final int batchSize = 20;
         int count = 0;
    
         for (int i=1; i<= total; i++ ) {
    
             // Define sql parameters
    
             statement.setString(1, p1);
    
             statement2.setString(1, p2);
             statement2.setString(2, p3);
    
             statement3.setInt(1, p4);
             statement3.setString(2, p5);
    
             statement.addBatch();
             statement2.addBatch();
             statement3.addBatch();
    
             if (++count % batchSize == 0) {
                        statement.executeBatch();
                        statement.clearBatch();
                        statement2.executeBatch();
                        statement2.clearBatch();
                        statement3.executeBatch();
                        statement3.clearBatch();
                        connection.commit();
                        System.out.println(i);
             }
          }
    
          statement.executeBatch();
          statement.clearBatch();
          statement2.executeBatch();
          statement2.clearBatch();
          statement3.executeBatch();
          statement3.clearBatch();
          connection.commit();
       } 
       catch (SQLException e) {
           e.printStackTrace();
       }
    }
    
    DataSource ds=jdbcTemplate.getDataSource();
    try(Connection=ds.getConnection();
    PreparedStatement=connection.prepareStatement(sql1);
    PreparedStatement语句2=connection.prepareStatement(sql2);
    PreparedStatement语句3=connection.prepareStatement(sql3);){
    connection.setAutoCommit(false);
    最终int batchSize=20;
    整数计数=0;
    
    对于(int i=1;iYes),假设大部分时间都花在等待数据库的响应上,那么它应该更接近。Spring有它自己的开销,因此客户端会有更多的资源消耗

    在使用占位符的准备好的语句中,Oracle只解析SQL一次,然后生成一次计划。然后,它会缓存解析结果以及SQL的计划。在JDBCTemplate示例中,每个SQL语句对于解析器来说都是不同的,因此需要服务器进行完整的解析和计划生成。具体取决于您r Oracle server的马力,这将导致每个SQL语句的响应时间增加。对于200000条SQL语句,1280秒的净增加将转化为每次调用额外的6.4毫秒。在我看来,由于需要额外的解析,这似乎是合理的增加


    我建议在数据库调用中添加一些计时信息,以便您可以确认改进版本中的SQL响应时间较低。

    对于任何给定的SQL,数据库引擎50%到80%的时间用于计算访问路径


    当您直接使用PreparedStatement时,数据库引擎会计算一次访问路径,并返回已计算访问路径的句柄(在“准备”阶段)。调用prepared语句时,数据库引擎只需将参数应用于已准备好的访问路径并返回光标。

    Spring JDBCTemplate也有使用prepared语句的方法。请参考此说明,您的测试结果有意义-您无法比较使用prepared语句和普通SQL的执行情况。

    SpringJDBCTemplate中有重载的batchUpdate方法,它使用准备好的语句,例如下面的函数

    int[]batchUpdate(字符串sql,最终集合batchArgs,最终 int batchSize,最终参数化PreparedStatementSetter(pss)

     List<String> bulkLoadRegistrationSql = new ArrayList<String>(20);
    
     for (int i=1; i<= total; i++ ) {
    
         // 1. Define sql parameters p1,p2,p,3p4,p5
    
         // 2. Prepare sql using parameters from 1
         String sql1String = ...
         String sql2String = ...
         String sql3String = ...
    
         bulkLoadRegistrationSql.add(sql1String);
         bulkLoadRegistrationSql.add(sql2String);
         bulkLoadRegistrationSql.add(sql3String);
    
         if (i % 20 == 0) {
              jdbcTemplate.batchUpdate(bulkLoadRegistrationSql
                  .toArray(new  String[bulkLoadRegistrationSql.size()]));
              //Clear inserted batch
              bulkLoadRegistrationSql = new ArrayList<String>(20);     
         }
    
    }