gpt4 book ai didi

java - Spring jdbcTemplate 与 PreparedStatement。性能差异

转载 作者:搜寻专家 更新时间:2023-11-01 03:18:56 26 4
gpt4 key购买 nike

我正在使用 Oracle 11g。我的数据库中有 3 个表(A,B,C)A <one-many> B <many-one> C我有一段代码,执行三个插入:首先在 AC , 然后在 B .这段代码被执行了很多次(200000)并使200000在每个表中插入操作。

我有两种插入方式:

  1. 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();
    }
    }
  2. Spring jdbcTemplate:

     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);
    }

    }

我测量了 total = 200000 的执行时间结果让我很困惑。 Spring jdbcTemplate在 1480 秒内执行,jdbc PreparedStatement在 200 秒内

我调查了 jdbcTemplate来源并发现,它使用 Statement在下面,这应该比 PreparedStatement 效率低.但是结果差异太大,我不确定这是否只是因为 Statement 之间的差异而发生的。和 PreparedStatement .你对此有何看法?如果jdbcTemplate,理论上结果应该相等吗?在 namedParameterJdbcTemplate 上被替换?

最佳答案

是的,它应该更接近,假设大部分时间都花在等待数据库的响应上。 Spring 有其自身的开销,因此您将在客户端消耗更多资源。

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

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

关于java - Spring jdbcTemplate 与 PreparedStatement。性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37464791/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com