2011-06-21 19 views
2

MySQL 5.5で最新のEclipseLinkバージョン(テーブルタイプInnoDB)を使用しています。私は一度に約30900のレコードを挿入しています。 問題は、挿入パフォーマンスが非常に悪いことです。すべてのレコードを挿入するのに約22秒かかります(JDBCと比較して:7秒)。私はバッチ執筆を助けるべきであることを読んだ - しかしない!データを挿入するとEclipseLinkが非常に遅くなる

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> 

@Entity 
public class TestRecord { 

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

    public int test; 
} 

コードは、レコードを挿入するには?私はいくつかの設定を試みましたが、何も助けに見えません。 私に手伝ってくれてありがとう! :)

-Stefan


もう一つは、コネクターが使用するデータのURLに?rewriteBatchedStatements=trueを追加することです。

これは約120300の挿入を約30秒まで実行したが、これは約60秒前であった。

答えて

5
@GeneratedValue(strategy = GenerationType.IDENTITY) 

TABLEシーケンシングに切り替え、IDENTITYは推奨しないと、主要なパフォーマンスの問題ありません。

私は、MySQLが同様に、いくつかのデータベースの設定なしで一括書き込みをサポートしていないことを覚えているようだ参照してください、 http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html

、この上の別の記事がありました、私は、URLを忘れていますが、おそらくそれを検索することができます。

+0

ありがとう!今は約9秒かかります。うまくいけばうまくいくはずです。 – Stefan

0

おそらく、マッピング変換以外の大きな違いはキャッシングです。デフォルトでは、EclipseLinkは各エンティティを永続コンテキスト(EntityManager)に配置しており、コミットの終了時にすべてをキャッシュに追加する必要があります。今のところ試して

ことの一つは、次のとおりです。

  1. 対策em.flush()の呼び出しは、ループの後でコミットする前にかかる時間。次に、フラッシュの後にem.clear()を呼び出して、新しく挿入されたエンティティがキャッシュにマージされないようにすることができます。

ダグ

+0

新しいテスト:

に例えば、それを試してみてください(em.flush 'なし)'インサートが、18Sほどかかります。コミットの直前に 'em.flush()'(17秒かかる)を呼び出すと、挿入は約18秒かかる。 'em.clear()'の追加は役に立ちません。 – Stefan

6

JDBCバッチ書込みはパフォーマンスを大幅に向上させます。 property name="eclipselink.jdbc.batch-writing" value="JDBC"

関連する問題