Java 对于修改,实体是缓慢的

Java 对于修改,实体是缓慢的,java,hibernate,hibernate-envers,Java,Hibernate,Hibernate Envers,我正在使用以下命令查询大于时间戳的类的所有修订: AuditReaderFactory .get(emf.createEntityManager()) .createQuery().forRevisionsOfEntity(clazz, false, true) .add(AuditEntity.revisionProperty("timestamp").gt(existingIndex.lastModified())) .getResultList(); 这是

我正在使用以下命令查询大于时间戳的类的所有修订:

AuditReaderFactory
    .get(emf.createEntityManager())
    .createQuery().forRevisionsOfEntity(clazz, false, true)
    .add(AuditEntity.revisionProperty("timestamp").gt(existingIndex.lastModified()))
    .getResultList();
这是使用查询重新创建@manytone引用的对象:

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或类似版本更快。我几乎想直接使用SQL,因为这太慢了。通过直接在子查询中使用id而不是引用查询的表id,也可以加快速度。我在DTYPE、REV和REVTYPE上有索引,在id、REV上有唯一键,所以这不是索引问题


我不确定它为什么要使用上面的查询来重新创建引用的对象,希望您能提供一些见解。这是在奔腾4机器上的MySQL 5.1数据库上实现的,但在双核机器上也需要相当长的时间。

hibernate 3.6.0版本的性能已显著提高。您应该使用ValidityAuditStrategy。将以下内容添加到persistence.xml中:

    <property name="org.hibernate.envers.audit_strategy"
              value="org.hibernate.envers.strategy.ValidityAuditStrategy"/>
这会将REVEND列添加到已审核的表中,因此不需要进行内部选择。阅读更多