PreparedStatement, CallableStatement и соображения производительности - PullRequest
12 голосов
/ 05 января 2012

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

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

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

  1. Можно ли использовать в моем случаеPreparedStatement вместо CallableStatement, учитывая, что хранимый процесс не имеет никаких параметров OUT?
  2. Есть ли какая-то причина, по которой PreparedStatement имеет какой-то прирост производительности по сравнению с CallableStatement, или это то, что я мог наблюдатьнеправильно?
  3. Есть ли лучший подход для решения этой проблемы производительности?

Ответы [ 2 ]

8 голосов
/ 05 января 2012

Из вашего комментария у вас есть 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 голосов
/ 17 сентября 2014

Разве вы не должны рассмотреть возможность использования партии?

conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall(sql);
while(true) {
    stmt.setInt(1, value);
    stmt.addBatch();
}
stmt.executeBatch()
conn.commit();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...