Мне нужно выполнить большое количество вставок (в данном случае 27k), и я хочу найти оптимальное решение для этого. Прямо сейчас это код, который у меня есть. Как вы можете видеть, я использую подготовленные операторы и пакеты и выполняю каждую 1000 (я также пробовал с меньшим числом, таким как 10 и 100, но время снова стало длинным). Одна вещь, которая пропускается в запросе, это то, что существует автоматически сгенерированный идентификатор, если он имеет какое-либо значение для проблемы:
private void parseIndividualReads(String file, DBAccessor db) {
BufferedReader reader;
try {
Connection con = db.getCon();
PreparedStatement statement = null;
statement = con.prepareStatement("INSERT INTO `vgsan01_process_log`.`contigs_and_large_singletons` (`seq_id` ,`length` ,`ws_id` ,`num_of_reads`) VALUES (?, ?, ?, ?)");
long count = 0;
reader = new BufferedReader(new FileReader(logDir + "/" + file));
String line;
while ((line = reader.readLine()) != null) {
if(count != 0 && count % 1000 == 0)
statement.executeBatch();
if (line.startsWith(">")) {
count++;
String res[] = parseHeader(line);
statement.setString(1, res[0]);
statement.setInt(2, Integer.parseInt(res[1]) );
statement.setInt(3, id);
statement.setInt(4, -1);
statement.addBatch();
}
}
statement.executeBatch();
} catch (FileNotFoundException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error opening file: " + file, ex);
} catch (IOException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error reading from file: " + file, ex);
} catch (SQLException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error inserting individual statistics " + file, ex);
}
}
Любые другие советы относительно того, что может быть изменено для ускорения процесса. Я имею в виду, что один оператор вставки не имеет много информации - я бы сказал, не более 50 символов для всех 4 столбцов
EDIT:
Хорошо, следуя приведенному совету, я перестроил метод следующим образом. Ускорение огромно. Вы даже можете попробовать поиграть со значением 1000, которое может дать лучшие результаты:
private void parseIndividualReads(String file, DBAccessor db) {
BufferedReader reader;
PrintWriter writer;
try {
Connection con = db.getCon();
con.setAutoCommit(false);
Statement st = con.createStatement();
StringBuilder sb = new StringBuilder(10000);
reader = new BufferedReader(new FileReader(logDir + "/" + file));
writer = new PrintWriter(new BufferedWriter(new FileWriter(logDir + "/velvet-temp-contigs", true)), true);
String line;
long count = 0;
while ((line = reader.readLine()) != null) {
if (count != 0 && count % 1000 == 0) {
sb.deleteCharAt(sb.length() - 1);
st.executeUpdate("INSERT INTO `vgsan01_process_log`.`contigs_and_large_singletons` (`seq_id` ,`length` ,`ws_id` ,`num_of_reads`) VALUES " + sb);
sb.delete(0, sb.capacity());
count = 0;
}
//we basically build a giant VALUES (),(),()... string that we use for insert
if (line.startsWith(">")) {
count++;
String res[] = parseHeader(line);
sb.append("('" + res[0] + "','" + res[1] + "','" + id + "','" + "-1'" + "),");
}
}
//insert all the remaining stuff
sb.deleteCharAt(sb.length() - 1);
st.executeUpdate("INSERT INTO `vgsan01_process_log`.`contigs_and_large_singletons` (`seq_id` ,`length` ,`ws_id` ,`num_of_reads`) VALUES " + sb);
con.commit();
} catch (FileNotFoundException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error opening file: " + file, ex);
} catch (IOException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error reading from file: " + file, ex);
} catch (SQLException ex) {
Logger.getLogger(VelvetStats.class.getName()).log(Level.SEVERE, "Error working with mysql", ex);
}
}