2

次を使用して、タイムスタンプより大きいクラスのすべてのリビジョンに対してクエリを実行しています。

AuditReaderFactory
    .get(emf.createEntityManager())
    .createQuery().forRevisionsOfEntity(clazz, false, true)
    .add(AuditEntity.revisionProperty("timestamp").gt(existingIndex.lastModified()))
    .getResultList();

これは@ManyToOne、クエリを使用して参照オブジェクトを再作成しています。

select <audit cols for this type> 
from <audit table> 
where DTYPE IN (<class type>) 
and REV=(
   SELECT max(REV) 
   FROM <audit table> 
   where TYPE IN (<class type>) 
   and REV <= <maximum revision in revision entity table> 
   and <subquery>.id=<query>.id
) 
and REVTYPE<>2 
AND <audit table>.id=<id of entity being restored>

このクエリは信じられないほど遅く、1 つのエンティティだけで 100 分以上かかります (実際、これを書いている現在も実行中です)。エンティティの最後のリビジョン (DEL リビジョンを除く) を取得しているのはなぜですか? を使用する方がはるかに高速ORDER BY REV LIMIT 1です (または を持たないデータベースの場合は同様ですLIMIT)。これは遅すぎるので、私はほとんどまっすぐにSQLに行きたいと思っています。また、クエリのテーブル ID を参照する代わりに、サブクエリ内で直接 ID を使用することで高速化することもできます。DTYPEREVおよびにインデックスがありREVTYPE、id に一意のキーREVがあるため、インデックス作成の問題ではありません。

上記のクエリを使用して参照されたオブジェクトを再作成する理由がわかりません。洞察をいただければ幸いです。これは、Pentium 4 マシン上の MySQL 5.1 データベースにありますが、デュアル コア マシンでもかなりの時間がかかります。

4

1 に答える 1

1

バージョン 3.6.0 の hibernate ではパフォーマンスが大幅に改善されました。あなたがすべきことは、ValidityAuditStrategy を使用することです。これを persistence.xml に追加します。

    <property name="org.hibernate.envers.audit_strategy"
              value="org.hibernate.envers.strategy.ValidityAuditStrategy"/>

これにより、監査対象のテーブルに REVEND 列が追加されるため、内部選択は必要ありません。詳細はこちらをご覧ください

于 2011-06-02T09:43:22.650 に答える