Ответ 1
Я буду решать ваши вопросы по очереди.
- Будет ли метод executeBatch одновременно отправлять все данные?
Это может варьироваться в зависимости от каждого драйвера JDBC, но те немногие, которые я изучил, будут перебирать каждую запись пакета и отправлять аргументы вместе с подготовленным дескриптором инструкции каждый раз в базу данных для выполнения. То есть в вашем примере выше будет 50 000 исполнений подготовленного оператора с 50 000 пар аргументов, но эти 50 000 шагов могут быть выполнены в "внутреннем цикле" нижнего уровня, в котором происходит сбережение времени. довольно растянутая аналогия, это как отказ от "пользовательского режима" вниз в "режим ядра" и запуск всего цикла выполнения там. Вы сохраняете стоимость погружения в и из этого режима нижнего уровня для каждой партии.
- Есть ли способ определить размер партии
Вы определили его неявно здесь, нажав 50 000 наборов аргументов перед выполнением пакета через Statement#executeBatch()
. Размер партии один так же важен.
- Есть ли лучший способ ускорить процесс объемной вставки?
Рассмотрите возможность открытия транзакции явно перед вставкой пакета и после этого завершите ее. Не позволяйте ни базе данных, ни драйверу JDBC накладывать границу транзакции на каждый шаг вставки в пакете. Вы можете управлять уровнем JDBC с помощью метода Connection#setAutoCommit(boolean)
. Сначала возьмите соединение из режима автоматической фиксации, затем заполните свои партии, запустите транзакцию, выполните пакет, затем совершите транзакцию через Connection#commit()
.
В этом совете предполагается, что ваши вставки не будут конкурировать с параллельными авторами и предполагают, что эти границы транзакций дадут вам достаточно согласованные значения, считанные из ваших исходных таблиц для использования в вставках. Если это не так, поддерживайте правильность по скорости.
- Лучше ли использовать обновляемый
ResultSet
илиPreparedStatement
с пакетным исполнением?
Ничто не сравнится с тестированием вашего драйвера JDBC по выбору, но я ожидаю, что последние будут PreparedStatement
и Statement#executeBatch()
. У дескриптора оператора может быть связанный список или массив "пакетных аргументов", причем каждая запись представляет собой набор аргументов, предоставляемый между вызовами Statement#executeBatch()
и Statement#addBatch()
(или Statement#clearBatch()
). Список будет расти с каждым вызовом addBatch()
, а не сбрасываться до тех пор, пока вы не назовете executeBatch()
. Следовательно, экземпляр Statement
действительно действует как буфер аргументов; вы торгуете памятью для удобства (используя экземпляр Statement
вместо вашего собственного внешнего буферного набора аргументов).
Опять же, вы должны учитывать эти ответы как общие, так и спекулятивные, пока мы не обсуждаем конкретный драйвер JDBC. Каждый драйвер отличается изощренностью, и каждый из них будет отличаться тем, какие оптимизации он преследует.