EclipseLink在插入数据时非常慢

时间:2011-06-21 14:08:45

标签: eclipselink

我正在使用MySQL 5.5的最新EclipseLink版本(表格型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>

我做错了什么?我尝试了几种设置,但似乎没有任何帮助。 在此先感谢您的帮助! :)

-Stefan


另一件事是将?rewriteBatchedStatements=true添加到连接器使用的数据URL。

这导致执行大约120300个插入到大约30秒,这是大约60秒之前。

3 个答案:

答案 0 :(得分:6)

JDBC批处理写法大大提高了性能;请试一试

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

答案 1 :(得分:5)

@GeneratedValue(strategy = GenerationType.IDENTITY)

切换到TABLE排序,永远不建议使用IDENTITY,这是一个主要的性能问题。

请参阅, http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html

我似乎记得MySQL可能不支持批量写入而没有一些数据库配置,还有另外一篇文章,我忘记了网址,但你可能会搜索它。

答案 2 :(得分:0)

除了映射转换之外,最大的区别可能是缓存。默认情况下,EclipseLink将每个实体放入持久化上下文(EntityManager),然后在提交完成期间,它需要将它们全部添加到缓存中。

现在要尝试的一件事是:

  1. 测量循环后但提交前em.flush()调用的时间。然后,如果你想要,你可以在刷新后调用em.clear(),以便新插入的实体不会合并到缓存中。
  2. 道格