更快地执行批量更新
Execute batch update faster
在一个旧项目中,我有一个 table,在 3 列上有 3 个索引,我正在执行批量查询(~= 5000 个更新查询),如 UPDATE mytable set mycolumn = 'blah' when myIndexedColumn = 'someId'
。
executeBatch 命令,大约需要1h:30,我使用oracle 11g 数据库,Java 6,Spring 批处理。有关 table 拥有 1 700 000 行。
Statement ps = null;
Connection connection = null;
try {
int counter = 0;
connection = myDatasource.getConnection();
connection.setAutoCommit(false);
ps = connection.createStatement();
for (String request : myListOfRequests) {
ps.addBatch(request);
}
ps.executeBatch();
connection.commit();
} catch (SQLException ex) {
LOGGER.error("My Errors : {}", ex.getMessage());
} finally {
if (ps != null) {
ps.clearBatch();
ps.close();
}
if (connection != null) connection.close();
}
我删除了索引,但没有发现明显的差异。我不能使用现代技术。删除和重建新的 table 也不是安全任务。那么你知道我该如何改进这个任务吗?
解决方案,最初由jawad abbassi在问题中发表:
感谢@curiosa,我已经使用 preparedStatement 而不是这样的语句:
PreparedStatement ps = null;
Connection connection = null;
String sql = "UPDATE MYTABLE SET COLUMN1 = ? WHERE COLUMN2 = ?";
try {
connection = myDataSource.getConnection();
connection.setAutoCommit(false);
ps = connection.prepareStatement(sql);
for (MyBean bean : myListOfBeans) {
ps.setBigDecimal(1, bean.getColumn1());
ps.setString(2, bean.getColumn2());
ps.addBatch();
}
ps.executeBatch();
} catch (SQLException ex) {
LOGGER.error("My errors : {}", ex.getMessage());
} finally {
if (ps != null) {
connection.commit();
ps.close();
connection.close();
}
}
在一个旧项目中,我有一个 table,在 3 列上有 3 个索引,我正在执行批量查询(~= 5000 个更新查询),如 UPDATE mytable set mycolumn = 'blah' when myIndexedColumn = 'someId'
。
executeBatch 命令,大约需要1h:30,我使用oracle 11g 数据库,Java 6,Spring 批处理。有关 table 拥有 1 700 000 行。
Statement ps = null;
Connection connection = null;
try {
int counter = 0;
connection = myDatasource.getConnection();
connection.setAutoCommit(false);
ps = connection.createStatement();
for (String request : myListOfRequests) {
ps.addBatch(request);
}
ps.executeBatch();
connection.commit();
} catch (SQLException ex) {
LOGGER.error("My Errors : {}", ex.getMessage());
} finally {
if (ps != null) {
ps.clearBatch();
ps.close();
}
if (connection != null) connection.close();
}
我删除了索引,但没有发现明显的差异。我不能使用现代技术。删除和重建新的 table 也不是安全任务。那么你知道我该如何改进这个任务吗?
解决方案,最初由jawad abbassi在问题中发表:
感谢@curiosa,我已经使用 preparedStatement 而不是这样的语句:
PreparedStatement ps = null;
Connection connection = null;
String sql = "UPDATE MYTABLE SET COLUMN1 = ? WHERE COLUMN2 = ?";
try {
connection = myDataSource.getConnection();
connection.setAutoCommit(false);
ps = connection.prepareStatement(sql);
for (MyBean bean : myListOfBeans) {
ps.setBigDecimal(1, bean.getColumn1());
ps.setString(2, bean.getColumn2());
ps.addBatch();
}
ps.executeBatch();
} catch (SQLException ex) {
LOGGER.error("My errors : {}", ex.getMessage());
} finally {
if (ps != null) {
connection.commit();
ps.close();
connection.close();
}
}