Вопрос по mysql, openjpa, java, performance – OpenJPA слияние / сохранение очень медленно

3

Я использую OpenJPA 2.2.0 на WebSphere Application Server 8 с БД MySQL 5.0.

У меня есть список объектов, которые я хочу объединить в БД.

это как:

for (Object ob : list) {
            Long start = Calendar.getInstance().getTimeInMillis();
            em = factory.createEntityManager();
            em.getTransaction().begin();

            em.merge(ob);

            em.getTransaction().commit();
            em.close();
            Long end = Calendar.getInstance().getTimeInMillis();
            Long diff = end - start;
            LOGGER.info("Time: " + diff);
        }

Когда я запускаю этот цикл, мне нужно около 300-600 миллисекунд для объединения одного объекта. Когда я удаляю строку «em.merge (ob);» тогда мне нужно "0" Миллисекунды для итерации по одному объекту списка.

Итак, мой вопрос: что я могу сделать, чтобы улучшить время объединения одного объекта?

Спасибо!

Включите вход в систему SQL, посмотрите, какие запросы генерируются, и посмотрите, какие из них требуют времени и почему. JB Nizet

Ваш Ответ

1   ответ
6

а затем зафиксировать ее в течение одной транзакции. Итак, в основном вы создаете пакет, который будет объединен / сохранен при коммите.

Кроме того, вы можете ограничить количество объектов в пакете, обрабатываемых за один раз, и можете явно сбрасывать изменения в базу данных.

Здесь вы инициируете транзакцию и фиксируете ее на каждой итерации, а также каждый раз создаете / закрываете менеджер сущностей, что повлияет на производительность для многочисленных данных.

Это будет что-то вроде приведенного ниже кода.

em = factory.createEntityManager();
em.getTransaction().begin();
int i = 0;

   for (Object ob : list) {
       Long start = Calendar.getInstance().getTimeInMillis();

       em.merge(ob);

       Long end = Calendar.getInstance().getTimeInMillis();
       Long diff = end - start;
       LOGGER.info("Time: " + diff);

       /*BATCH_SIZE is the number of entities 
            that will be persisted/merged at once */

       if(i%BATCH_SIZE == 0){    
           em.flush();
           em.clear(); 
       }

       i++;
   }

em.getTransaction().commit();
em.close();

Здесь вы также можете откатить всю транзакцию, если какой-либо объект не может быть сохранен / объединен.

@ veote Добро пожаловать и рад, что это помогло. Nayan Wadekar
Большое спасибо, это работает очень хорошо! veote
спасибо, я пробовал это раньше, но чем больше у меня объектов, тем медленнее будет процесс слияния, в моем списке около 4000 объектов veote
@ veote Как я уже упоминал, вы можете явно ограничить количество объектов. В код добавлена пакетная логика, в которой можно указать соответствующий размер пакета (например, взять 100, тогда изменения в 100 объектах будут сразу же отражены в базе данных), см. Код. Nayan Wadekar

Похожие вопросы