Подтвердить что ты не робот

PreparedStatement, CallableStatement и оценки производительности

У меня есть oracle stored proc, который нужно вызвать из моей программы Java. Я использовал CallableStatement для передачи параметров хранимому процессу. Я использую тонкий драйвер oracle (настроенный на сервере веб-логики против соответствующей записи jndi). Этот хранимый proc не имеет никаких значений OUT. Этот сохраненный proc принимает числовое значение и делает много обновлений в базе данных на основе полученного значения.

Я получаю объект соединения, а затем вызываю этот сохраненный цикл proc (20 раз для передачи 20 номеров). Когда я напрямую вызываю этот хранимый процесс от клиента oracle, выполнение завершается через 2-3 секунды. Однако поведение не предсказуемо из моего java-кода. Некоторые из звонков занимают 30-40 секунд, чтобы завершить работу.

Я попытался использовать PreparedStatement вместо CallableStatement и мог видеть незначительное улучшение производительности (хотя поведение по-прежнему несовместимо).

  • Хорошо ли в моем случае использовать PreparedStatement вместо CallableStatement, учитывая, что у хранимогопрограммы нет каких-либо параметров OUT?
  • Есть ли причина, по которой PreparedStatement имеет некоторое усиление производительности по сравнению с CallableStatement или это то, что я мог бы заметить неправильно?
  • Есть ли лучший способ решения этой проблемы производительности?
4b9b3361

Ответ 1

Из вашего комментария у вас есть prepareCall внутри вашей петли. Преимущество подготовленных операторов (и вызываемых утверждений) состоит в том, что вы можете подготовить его один раз, а затем поменять значения, переданные в параметрах; есть накладные расходы каждый раз, когда вызов готов, поэтому, если вы можете вывести это за пределы своего цикла, вы можете обнаружить, что время выполнения уменьшается. Вы можете обнаружить, что отключение AutoCommit также помогает, поскольку на каждой фиксации есть накладные расходы.

conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
    stmt.setInt(1, value);
    stmt.execute();
}
conn.commit();
conn.setAutoCommit(true);

(conn.setAutoCommit(true) делает фиксацию, но я нахожу ее яснее).

Ответ 2

Не следует ли вам использовать пакет?

conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
    stmt.setInt(1, value);
    stmt.addBatch();
}
stmt.executeBatch()
conn.commit();