EclipseLink очень медленно вставляет данные

Я использую последнюю версию EclipseLink с MySQL 5.5 (табличный тип InnoDB). Я вставляю около 30900 записей (может быть и больше) за раз. Проблема в том, что производительность вставки довольно низкая: вставка всех записей занимает около 22 секунд (по сравнению с JDBC: 7 секунд). Я читал, что использование пакетной записи должно помочь, но не помогает!?

@Entity
public class TestRecord {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    public int test;
}

Код для вставки записей:

factory = Persistence.createEntityManagerFactory("xx_test");
EntityManager em = factory.createEntityManager();

em.getTransaction().begin();

for(int i = 0; i < 30900; i++) {
    TestRecord record = new TestRecord();
    record.test = 21;
    em.persist(record);
}

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

И, наконец, моя конфигурация EclipseLink:

<persistence-unit name="xx_test" transaction-type="RESOURCE_LOCAL">
    <class>com.test.TestRecord</class>

    <properties>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/xx_test" />
        <property name="javax.persistence.jdbc.user" value="root" />
        <property name="javax.persistence.jdbc.password" value="test" />

        <property name="eclipselink.jdbc.batch-writing" value="JDBC" />
        <property name="eclipselink.jdbc.cache-statements" value="true"/>   

        <property name="eclipselink.ddl-generation.output-mode" value="both" />
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />

        <property name="eclipselink.logging.level" value="INFO" />
    </properties>
</persistence-unit>

Что я делаю неправильно? Я пробовал несколько настроек, но ничего не помогает. Заранее спасибо за помощь! :)

-Стефан


Другое дело — добавить ?rewriteBatchedStatements=true к URL-адресу данных, используемому коннектором.

Это привело к выполнению около 120300 вставок примерно до 30 секунд, что раньше было около 60 секунд.


person Stefan    schedule 21.06.2011    source источник


Ответы (3)


@GeneratedValue(strategy = GenerationType.IDENTITY)

Переключитесь на последовательность TABLE, IDENTITY никогда не рекомендуется и является серьезной проблемой производительности.

См. http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html

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

person James    schedule 23.06.2011
comment
Большое спасибо! Теперь это занимает около 9 секунд, что должно быть хорошо, надеюсь. - person Stefan; 27.06.2011

Пакетная запись JDBC значительно повышает производительность; Пожалуйста, попробуйте

Eg: property name="eclipselink.jdbc.batch-writing" value="JDBC"

person Hilal    schedule 20.06.2012

Вероятно, самым большим отличием, помимо преобразования отображения, является кэширование. По умолчанию EclipseLink помещает каждую из сущностей в контекст сохраняемости (EntityManager), а затем во время завершения фиксации необходимо добавить их все в кеш.

Одна вещь, которую нужно попробовать сейчас:

  1. измерить, сколько времени занимает вызов em.flush() после цикла, но до фиксации. Затем, если вы хотите, вы можете вызвать em.clear() после сброса, чтобы вновь вставленные объекты не были объединены в кеш.

Дуг

person Doug Clarke    schedule 21.06.2011
comment
Новый тест: без em.flush() вставка занимает около 18 секунд. При вызове em.flush() (занимает 17 секунд) непосредственно перед фиксацией вставка также занимает около 18 секунд. Добавление em.clear() тоже не помогает. - person Stefan; 22.06.2011