最近我们更改了连接池以迁移到 Oracle UCP。在迁移之前,我们使用了嵌入了 oracle jdbc 驱动程序 (ojdbc6.jar) 的池。
我们的问题是绑定变量阶段经过的时间。使用 UCP,绑定变量的时间比旧池长,因为它使用自省。
在正常情况下(选择或更新),绑定变量的时间与执行 sql 查询的时间相比非常小。但是,当我们使用 PreparedStatement 进行批处理执行时,我们会执行很多绑定变量,有时我们会通过调用 pst.excuteBatch() 来运行查询。
例如,这是一个小程序来说明两个池的经过时间。
PreparedStatement ppst = connection.prepareStatement(INSERT_SQL);
...
private long setParam(PreparedStatement prepStmt) throws SQLException {
long d = 0;
for (long i = 1; i <= 750 000; i++) {
int index = 1;
prepStmt.setString(index++, "1470");
prepStmt.setTimestamp(index++, new Timestamp(System.currentTimeMillis()));
prepStmt.setInt(index++, 1);
prepStmt.setObject(index++, String.valueOf(i));
prepStmt.addBatch();
}
prepStmt.clearBatch();
return d;
}
使用嵌入了 ojdbc6 驱动程序的旧池,经过的时间为:7.653 秒。
使用 UCP 池,经过的时间为:10.92 秒。
在这个例子中,我们有 750 000 次迭代和 4 个绑定变量。在我们的生产批次中,我们有 50 000 000 次迭代。所以绑定变量的时间很长,我们的批处理时间也变长了。
技术信息:
旧池:ojdbc6.jar (11.2.0.3.0)
新池:ojdbc6.jar (11.2.0.3.0) + ucp.jar (11.2.0.4.0)
我们已经分析了绑定变量阶段:
- 使用新的池 UCP,每个变量都与较慢的 java reelection api 绑定。
- 使用旧池,每个变量都直接与变量类型的相应方法绑定。
我们如何提高 UCP 池的绑定变量的性能?你知道一种禁用java反射api的方法吗?