我正在使用 Oracle 11g。我的A,B,C数据库中有 3 个表()A <one-many> B <many-one> C
我有一段代码,它执行三个插入:首先是 inA和C,然后是 in 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();
}
}
Run Code Online (Sandbox Code Playgroud)弹簧 jdbc 模板:
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);
}
}
Run Code Online (Sandbox Code Playgroud)我测量了执行时间total = 200000,结果对我来说非常混乱。spring jdbcTemplate1480秒执行,jdbc PreparedStatement200秒
我查看了jdbcTemplate源代码,发现它Statement在下面使用,效率应该低于PreparedStatement. 然而,结果差异太大,我不确定这是否仅仅因为 和 之间的差异Statement而发生PreparedStatement。你对此有何想法?如果jdbcTemplate替换为 ,理论上的结果应该相等namedParameterJdbcTemplate吗?
是的,它应该更接近,假设大部分时间都花在等待数据库的响应上。Spring 有其自身的开销,因此您将在客户端消耗更多的资源。
在使用占位符的预准备语句中,Oracle 仅解析一次 SQL,并生成一次计划。然后它会缓存解析结果以及 SQL 计划。在 JDBCTemplate 示例中,每个 SQL 语句对于解析器来说看起来都不同,因此需要服务器进行完整的解析和计划生成。根据 Oracle 服务器的性能,这将导致每个 SQL 语句的响应时间增加。对于 200,000 个 SQL 语句,净增加 1280 秒意味着每次调用额外花费 6.4 毫秒。对我来说,由于需要额外的解析,这似乎是一个合理的增长。
我建议在数据库调用中添加一些计时信息,以便您可以确认改进版本中的 SQL 响应时间较低。
| 归档时间: |
|
| 查看次数: |
9070 次 |
| 最近记录: |