Сравнение производительности между mybaits Batch ExecutorType и for_each Xml

У меня есть список записей, которые нужно вставить в БД с помощью моих приманок. Раньше мой код выглядел примерно так:

for(Item item :  items){
    sqlSession.insert("insert", item);
}

Использование этого метода работает, но я обнаружил, что на сервере Mysql есть динамический инкрементный DiskIO из-за количества элементов.

Поскольку у меня мало доступа к конфигурации MySql, и я надеюсь решить эту проблему с большим объемом дискового ввода-вывода, я нахожу несколько возможных решений:

  1. используя ExecutorType.BATCH для sqlSession
  2. вставить несколько значений в один оператор вставки, например: insert into Item values <foreach collection="list" item="item" index="index" separator=","> (#{item.a}, #{item.b}...) </foreach>

Кто-нибудь знает, какой из них подходит для решения моей проблемы с высоким diskIO и в чем основное различие между этими двумя решениями? Спасибо.


person shijie xu    schedule 08.05.2019    source источник


Ответы (1)


Хотя трудно предсказать влияние на дисковый ввод-вывод вашего сервера, рекомендуемым способом является метод 1 (с использованием ExecutorType.BATCH).
Он в основном вставляет определенное количество элементов за один раз.
Поскольку он внутренне использует API пакетных операций JDBC, который предназначен для обработки многих строк, вы можете извлечь выгоду из оптимизации драйвера.

Заметки:

  • Очень важно найти правильный «размер партии». См. пример кода в другом ответе.
  • В случае MySQL добавьте rewriteBatchedStatements=true к URL-адресу подключения обычно значительно повышает производительность.

Метод 2 (многострочная вставка) выполняет один оператор, связывающий все элементы одновременно.
Это может вызвать проблемы с памятью.

person ave    schedule 08.05.2019
comment
Что вы имеете в виду под «Это может вызвать проблемы с памятью»? - person shijie xu; 10.05.2019
comment
Предполагая, что вы вставляете миллион элементов и в каждой строке есть десять столбцов, оператор содержит десять миллионов заполнителей (т. е. ? в PreparedStatement). И драйвер должен хранить все параметры в памяти, пока не будет вызван execute(). - person ave; 10.05.2019