Делаю так:
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO mydbcall1.Call0 (date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone)" +
" VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
try {
ps.setDate(1, new java.sql.Date(call.date.getTime()) );
ps.setString(2, call.direction);
ps.setString(3, call.operator);
ps.setString(4, call.abonentTel);
ps.setInt(5, call.duration);
ps.setDouble(6, call.coast1);
ps.setDouble(7, call.coast2);
ps.setString(8, call.corpPhone);
ps.executeUpdate(); // for INSERT, UPDATE & DELETE
} finally {
ps.close();
}
метод для 3000 объектов работает больше 1.5 минут.
Ответ
Не создавайте PreparedStatement каждый раз заново. Преимущество PreparedStatement перед обычным Statement именно в том, что можно его заранее отправить на сервер БД для компиляции и переиспользовать повторно.
Отправляйте вставки пакетами (batch). Вероятно, вам придется подобрать оптимальный размер пакета.
Используйте явное управление транзакцией. По-умолчанию транзакция завершается на каждый запрос к БД (autoCommit = true).
Вот пример с применением этих трех рекомендаций (используется try-with-resources):
private static final String INSERT_STATEMENT = "INSERT INTO mydbcall1.Call0(date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
// ....
try (
Connection connection = database.getConnection();
PreparedStatement ps = connection.prepareStatement(INSERT_STATEMENT);
) {
int i = 0;
connection.setAutoCommit(false)
for (Call call : calls) {
ps.setDate(1, new java.sql.Date(call.date.getTime()) );
ps.setString(2, call.direction);
ps.setString(3, call.operator);
ps.setString(4, call.abonentTel);
ps.setInt(5, call.duration);
ps.setDouble(6, call.coast1);
ps.setDouble(7, call.coast2);
ps.setString(8, call.corpPhone);
// ...
ps.addBatch();
i++;
if (i % 1000 == 0 || i == calls.size()) {
ps.executeBatch(); // ограничиваем размер одного пакета тысячей вставок
}
}
connection.commit();
} catch(SQLException e) {
connection.rollback();
}
Комментариев нет:
Отправить комментарий