java - forRevisionsOfEntity 很慢

标签 java hibernate hibernate-envers

我正在查询大于时间戳的类的所有修订,使用:

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(或类似的数据库没有 LIMIT)要快得多。我几乎想直接使用 SQL,因为这太慢了。也可以通过直接在子查询中使用 id 而不是引用查询的表 id 来加快速度。我在 DTYPEREVREVTYPE 上有索引,在 id 上有一个唯一键,REV 所以它不是不是索引问题。

我不确定它为什么使用上述查询来重新创建引用的对象,如果有任何见解,我将不胜感激。这是在 Pentium 4 机器上的 MySQL 5.1 数据库上,但在双核机器上也需要相当长的时间。

最佳答案

性能在 3.6.0 版本的 hibernate 中得到了显着提高。你应该做的是使用 ValidityAuditStrategy。将此添加到您的 persistence.xml:

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

这会将 REVEND 列添加到您的审计表中,因此不需要内部选择。阅读更多 here .

关于java - forRevisionsOfEntity 很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5084754/

相关文章:

Java在arraylist中排序数字

java - JPQL查询异常异常AST节点: {vector}

java - 更新在 Hibernate 多对多关系表中不起作用

java - 线程和 hibernate session 的问题

java - 如何在使用 Hibernate 更新时将数据库字段值重置为默认值?

java - Hibernate Envers - 不为 createQuery(...).executeUpdate() 编写审计记录,只为 .persist() 和 .merge()

java - 带有 envers 的应用程序在架构验证 : REV column is of wrong type - found [int8 (Types#BIGINT)], 上失败,但需要 [int4 (Types#INTEGER)]

java - 根据描述创建对象

java - `new`关键字有什么作用

Java 监控数据库的变化 - Hibernate 和 envers