5

AUTO_INCREMENT ( http://scn.sap.com/thread/3238906 )をサポートしていない SAP HANA インメモリ データベースに Hibernate を接続しようとしているときに、いくつかのパフォーマンスの問題に直面しています。

そのため、ID 生成にシーケンスを使用するように Hibernate を設定しました。

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") 
  @SequenceGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1)

しかし、大量のレコード (たとえば 40000) を挿入すると、Hibernate は最初に ID を生成します。次のようになります。

DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY
DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92080]]
DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92080, using strategy: org.hibernate.id.SequenceHiLoGenerator
DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY
DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92081]]
DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92081, using strategy: org.hibernate.id.SequenceHiLoGenerator

そして、すべての ID が生成された後でのみ、実際の挿入が開始されます。

全体として、40000 レコードを (ネットワーク経由でリモート データベースに) 挿入するのに約 5 分かかります。これは、インメモリ データベースでは非常に時間がかかります。Hibernate が ID の次の値を 1 つずつ選択するために発生すると思います。

send a request to database
get id
send next request
...

ID 生成を高速化したいのですが、残念ながら、それがどのように機能するのかを十分に理解していないため、改善することができません。考えられる解決策を探したところ、次のアイデアが見つかりました。

1) insert ステートメント内で sequence.nextval を呼び出します。ただし、Hibernate チームはそれは不可能だと言っています: https://forum.hibernate.org/viewtopic.php?f=1&t=932506

2) SequenceHiLoGenerator を使用します。これは解決策かもしれませんが、設定方法がわかりません...

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") 
  @SequenceHiLoGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1),

Eclipse で「SequenceHiLoGenerator から Annotation に変換できません」というエラーが表示される

3) inserts にデータベース トリガーを記述します。しかし、私はユニバーサル Hibernate Dialect を任意のデータベース インスタンスで動作させたいので、これは悪い解決策のように見えます。そして、そのようなトリガーを Hibernate Dialect に含める方法がわかりません。

どのソリューションを提案しますか? 他にアイデアはありますか?

この質問についてお役に立てれば幸いです。誰かが解決策やドキュメント、または解決策へのより詳細な経路を提供できれば素晴らしいことです。

事前にどうもありがとうございました。

4

1 に答える 1

5

allocationSizeが 1 に設定されているため、シーケンスからの値は 1 つずつフェッチされますallocationSize。この特定のケースでは、40000 レコードの挿入が一般的な使用例である場合、それよりも高い値を使用することはおそらく理にかなっています。

シーケンスを作成するスクリプトが (Hibernate によってではなく) 自己記述されている場合、 の値は のINCREMENT BY値と同じである必要がありallocationSizeます。

于 2013-03-11T18:39:13.297 に答える