Java Spring jdbcTemplate vs PreparedStatement。性能差异
我正在使用Oracle11g。我的数据库中有3个表(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
A、B、C
)
我有一段代码,它执行三次插入:首先插入a
和C
,然后插入B
。这段代码执行了很多次(200000
),并在每个表中执行200000
插入操作
我有两种插入方式:
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);
}
}