【问题标题】:Performance of queries in Hibernate EnversHibernate Envers 中的查询性能
【发布时间】:2012-11-07 14:27:17
【问题描述】:

我们目前在一个项目中使用 Envers,当我们查询分布在多个表中的一些经过审计的数据时,性能会下降很多。

基本上我们创建一个审计数据流如下:

List<Object[]> auditStream = new LinkedList<Object[]>();
for (Class<?> entityClass : desiredEntityClasses) {
    auditStream.addAll(
        auditReader.createQuery()
            .forRevisionsOfEntity(entityClass, false, true)
            .add(AuditEntity
                .revisionProperty("timestamp")
                .ge(startTimestamp))
            .getResultList());    
} 

除此之外,某些类型的实体(如嵌套实体)还需要一些额外的审计信息。

对于少量数据(通过减少时间戳)的响应时间是合理的,但是auditStream 中有 500 个条目,大约需要 3 秒才能得到所有数据,这太长了。

Q1我想知道是否可以对这类查询启用批量获取以及如何启用?

Q2有没有办法优化查询,例如一次获取多种实体?

【问题讨论】:

    标签: java hibernate hibernate-envers


    【解决方案1】:

    一个 Audition 是多个表中更改的集合!

    如果您使用 REVID 引用的修订表 (REVINFO),则将检查所有其他表是否匹配此 REVID 的更改。

    Q1:并非所有依赖表的更改都取决于您的 Entity-Audition,Batch-Fetch 不能在这里工作。

    Q2:您最好直接通过 HQL 或纯 SQL 获取更改。

    【讨论】:

    • 感谢您的回答。然而,envers 似乎不支持 HQL。您能否进一步解释一下您的陈述:[如果您使用 REVID 引用的修订表 (REVINFO),则将检查所有其他表是否匹配此 REVID 的更改]
    • Hibernate 是“可交易的”,因此您在一个事务中更改多个表并将这些更改提交到数据库到特定的时间戳/时区。为了封装这些更改,您将在表试听中成为一个名为“Revid”的新列,其中包含 REVINFO 表中包含执行时间戳的一个条目的外键。因此,每个事务都成为 REVINFO 表中的一个条目。
    【解决方案2】:

    为了有效地实现这一点,您需要有关在单个表中的修订中所做的所有更改的信息 - 现在您正在查询多个。

    在 Envers 方面,也许这会有所帮助: http://docs.jboss.org/hibernate/core/4.0/devguide/en-US/html/ch15.html#envers-tracking-modified-entities-revchanges 通过这种方式,您可以获得在修订时更改的实体的名称,但我不确定您对流的要求是什么 - 您需要返回给最终用户。

    否则,我认为您必须实施一些自定义修改/将必要的“流”数据存储在单独的实体中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2020-09-12
      • 2018-11-16
      • 2013-05-24
      • 2010-12-19
      • 1970-01-01
      相关资源
      最近更新 更多