2016-06-24 6 views
3

3つのテーブルに15000を超える行を挿入/更新する必要があります。つまり、合計45kのインサートです。ステートレスセッションを使用した一括挿入/更新 - 休止状態

私は、コンテキストキャッシュを持たないため、バッチ処理に最適であることをオンラインで読んだあと、hibernateでStatelesssessionを使用しました。

session = sessionFactory.openStatelessSession; 
for(Employee e: emplList) { 
    session.insert(e); 
} 
transcation.commit; 

しかし、このコードは完了するまでに1時間以上かかります。

エンティティオブジェクトをすべて一度に保存する方法はありますか? コレクションを1つずつ保存するのではなく、保存しますか?

編集:クイック挿入を提供できる他のフレームワークはありますか?

乾杯!

+0

単純なセッションで 'hibernate.order_inserts'と' hibernate.order_updates'を試しましたか?また、Employeeを1つ保存するときに実行されるSQL文を表示できますか? –

答えて

1

あなたはヴラッド・ミホールセアのこの記事をお読みください:

How to batch INSERT and UPDATE statements with Hibernate

+0

記事ごとに、私はbatch_sizeを使う必要があると言いますが、挿入するのに同じ時間がかかります。 –

1

あなたは休止状態プロパティを設定したことを確認する必要があります。

hibernate.jdbc.batch_size

Hibernateはバッチことができるようにこれらの挿入物は、一度に1つずつ挿入されます。

+0

私はこれを通常のセッションで疲れましたが、それでも同じ時間がかかります。 –

1

すべてのエンティティを一度に挿入する方法はありません。 session.save(emplList)のようなことを内部で行っても、Hibernateは1つずつ保存します。したがって、バッチ機能を使用していないユーザーガイドStatelessSessionを休止する

いるinsert()、update()、およびdelete()StatelessSessionインターフェースで定義されている操作は、データベースの行を直接操作。これにより、対応するSQL操作は、のすぐに実行されるになります。 Sessionインタフェースで定義されたsave()、saveOrUpdate()、およびdelete()操作とは異なるセマンティクスを持ちます。

代わりに通常のセッションを使用し、時々キャッシュをクリアしてください。実際には、まずコードを測定してからhibernate.jdbc.batch_sizeのような変更を加えることをお勧めします。

はこのようにそれを変更してください:

session = sessionFactory.openSession(); 
int count = 0; 
int step = 0; 
int stepSize = 1_000; 
long start = System.currentTimeMillis(); 
for(Employee e:emplList) { 
    session.save(e); 
    count++; 
    if (step++ == stepSize) { 
     long elapsed = System.currentTimeMillis() - start; 
     long linesPerSecond = stepSize/elapsed * 1_000; 
     StringBuilder msg = new StringBuilder(); 
     msg.append("Step time: "); 
     msg.append(elapsed); 
     msg.append(" ms Lines: "); 
     msg.append(count); 
     msg.append("/"); 
     msg.append(emplList.size()); 
     msg.append(" Lines/Seconds: "); 
     msg.append(linesPerSecond); 
     System.out.println(msg.toString()); 
     start = System.currentTimeMillis(); 
     step = 0; 
     session.clear(); 
    } 
} 
transcation.commit; 

についてhibernate.jdbc.batch_size - あなたが使用してネットワーク構成で基礎となるデータベースに応じて、いくつかの非常に大きな含めて異なる値を、試すことができます。たとえば、アプリケーションサーバーとデータベースサーバーの間の1Gbpsネットワークには10,000の値を使用し、毎秒20,000レコードを提供します。

stepSizeを同じ値hibernate.jdbc.batch_sizeに変更してください。

+0

基本的には、私はこれらの多くの挿入にかかる時間を短縮できないと言っています。このようなものを提供する他のフレームワークはありますか? –

+0

いいえ、jdbcベースです。 – DiogoSantana

+0

バッチjdbcバッチ・インサートを使用する方が速くなります。通常のHibernateセッションを使用し、 'hibernate.jdbc_batch_size'を変更してください。 – DiogoSantana