Гарантии пакетного выполнения JDBC

Мы пытаемся выполнить пакетную вставку в Azure Synapse (ранее - хранилище данных SQL Azure). Проблемы:

  • Производительность ужасная (~ 1 секунда для вставки одной строки размером менее 2 КБ и 20-25 столбцов)
  • Он масштабируется линейно (я думаю, ~ 90 секунд для 100 строк)

Мы используем стандартный шаблон пакетной вставки JDBC addBatch() & executeBatch() с PreparedStatements (https://stackoverflow.com/a/3786127/496289).

Мы используем драйвер JDBC, предоставленный Microsoft.

Мы знаем, что не так, в телеметрии БД ясно, что БД разбивает пакет и более или менее запускает его, как если бы он был в цикле for. Нет пакетной оптимизации.

Любопытно, что когда базовым источником данных является SQL Server, пакетное масштабирование выполняется должным образом.

Вопрос: Нет ли в стандарте / спецификации ничего, что говорило бы, что executeBatch() должен масштабироваться лучше, чем линейно?

Например. JDBC™ 4.3 Specification (JSR 221) говорит, что он может повысить производительность, а не должен.

ГЛАВА 14 Пакетные обновления

Средство пакетного обновления позволяет одновременно отправлять несколько операторов SQL в источник данных для обработки. Отправка нескольких операторов SQL, а не по отдельности, может значительно повысить производительность. Объекты Statement, PreparedStatement и CallableStatement могут использоваться для отправки пакетных обновлений.

14.1.4 PreparedStatement Objects не имеет такого явного / подразумеваемого утверждения, что пакетный механизм предназначен для повышения производительности.


Вероятно, следует добавить, что Azure Synapse способен загрузить 1 триллион строк данных (~ 450 ГБ в формате Parquet) из озера данных за 17-26 минут с 500 DWU.


person Kashyap    schedule 05.05.2020    source источник
comment
Вы не сказали нам, какую производительность вы наблюдаете без пакета (с использованием одного PreparedStatement для INSERT). Основное различие при использовании пакетной обработки заключается в сохранении двустороннего обращения для каждой вставленной строки. Хорошая новость, IMHO, заключается в том, что даже если вы наблюдаете повторяющиеся вставки одной строки в БД, это не может объяснить одну секунду прошедшего времени для каждой строки. Так что должно быть другое (вероятно, тривиальное) объяснение.   -  person Marmite Bomber    schedule 05.05.2020
comment
@MarmiteBomber, без батча ~ 1 сек / ряд. - So there must be an other (probale trivial) explanation: Не совсем, у нас были обширные тесты / отладка, и Azure поднял руки, говоря, что это ожидается. Так что нет никаких тривиальных или нетривиальных объяснений, это просто производительность. Добавление еще одного утверждения о производительности в конце вопроса.   -  person Kashyap    schedule 05.05.2020


Ответы (1)


Спецификация JDBC не требует какой-либо оптимизации для пакетного выполнения. Фактически, не все базы данных поддерживают пакетное выполнение. Ожидается, что соответствующий драйвер JDBC будет реализовывать пакетное выполнение независимо от того, поддерживает ли это базовая система баз данных.

Если система баз данных не поддерживает это, драйвер JDBC будет имитировать пакетное выполнение, многократно выполняя инструкцию в цикле. Такая реализация не будет работать лучше, чем многократное выполнение оператора вручную.

По этой же причине в цитируемом вами тексте говорится «может значительно повысить производительность», а не будет или обязательно.

person Mark Rotteveel    schedule 05.05.2020