[英]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.