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>

这个查询非常慢,仅针对一个实体就需要 100 多分钟(事实上,在我写这篇文章的时候它还在继续)。为什么它会获得实体的最新版本(减去 DEL 版本)?ORDER BY REV LIMIT 1使用 a (或类似的数据库没有)要快得多LIMIT。我几乎只想直接使用 SQL,因为这太慢了。它也可以通过直接在子查询中使用 id 而不是引用查询的表 id 来加速。我在DTYPE,REVREVTYPE, 上有索引,在 id 上有一个唯一键,REV所以这不是索引问题。

我不确定它为什么要使用上述查询来重新创建引用的对象,并希望有任何见解。这是在奔腾 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 回答