[英]Fastest way to batch query an ORACLE Database with Java
在我正在进行的一个项目中,我得到的列表包含少于一百万行。 数据将所有可能的起点(000-999)映射到所有可能的目的地(000-999)。
对于每种组合,我需要能够查看数据库并确定是否存在具有相同组合的记录。 如果不存在任何记录,那么它将被添加到数据库中。 如果记录确实存在,那么将使用新信息更新记录。
源和目标是表的主键,也是索引。 所有这些都在ORACLE数据库上。
鉴于我必须这样做一百万次,最佳的解决方案是什么? 我当前的方法需要一个多小时才能处理所有记录。
对于实际插入和更新记录,我使用的是批量查询过程,该过程根本不需要花费很多时间。
看起来花费最多时间的部分是查询数据库中现有记录的数量。
public String batchUpdateModes(List records, String user) throws TransactionException {
String message = "";
ArrayList updateList = new ArrayList();
ArrayList insertList = new ArrayList();
Connection conn = null;
try {
conn = getDao().getConnection();
} catch (SQLException e1) {
e1.printStackTrace();
}
for (int i = 0; i < records.size(); i++) {
BatchFileCommand record = (BatchFileCommand)records.get(i);
String origin = record.getOrigZip().trim();
String dest = record.getDestZip().trim();
String pri = record.getPriMode().trim();
String fcm = record.getFcmMode().trim();
String per = record.getPerMode().trim();
String pkg = record.getPkgMode().trim();
String std = record.getStdMode().trim();
String effDate = record.getEffDate();
String discDate = "";
TransModeObj obj = new TransModeObj(origin, dest, pri, fcm, per, pkg, std, effDate, discDate);
obj.setUserId(user);
try {
Statement stmt = null;
String findExisting = "select count(*) from trans_mode where orig_zip = " + origin + " " +
"and dest_zip = " + dest;
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(findExisting);
int count = 0;
while (rs.next()) {
count = rs.getInt(1);
}
if (count > 0) {
updateList.add(obj);
}
else {
insertList.add(obj);
}
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
message = e.getMessage();
}
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
boolean success = false;
recordCount[0] = updateList.size();
recordCount[1] = insertList.size();
success = insertTransModes(insertList);
System.out.println("Inserts Complete");
success = updateTransModes(updateList);
System.out.println("Updates Complete");
if (success) {
message = "success";
}
else {
message = "The changes or additions submitted could not be completed.";
}
return message;
最简单的解决方案是放弃计数,而仅使用MERGE语句。 这使数据库可以确定是在单个SQL事务中插入还是更新。 了解更多。
MERGE的一个缺点是,行数不能区分更新的行和插入的行。 这可能是为节省整体时间付出的便宜价格。 尽管如果真的不能没有单独的统计, Adrian Billington可以为您提供解决方法 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.