Hibernate 优化:急切获取基本域类实例

Hibernate 优化:急切获取基本域类实例,hibernate,grails,gorm,query-performance,grails-2.3,Hibernate,Grails,Gorm,Query Performance,Grails 2.3,Grails应用程序维护有关已保存文档的数据 class Document { } class Image extends Document { } class ACL { Collection documents static mapping = { documents lazy: false, batchSize: 100 } } 为名为文档的基本域类创建域类的简单层次结构 目前使用的是表/子类方法。这不是最有效的,但目前还可以 对文档的访问由ACL控制,A

Grails应用程序维护有关已保存文档的数据

class Document {
}

class Image extends Document {
}

class ACL {
  Collection documents
  static mapping = {
     documents   lazy: false, batchSize: 100
  }

}
为名为
文档的基本域类创建域类的简单层次结构

目前使用的是表/子类方法。这不是最有效的,但目前还可以

对文档的访问由ACL控制,ACL由另一个域类建模

在一种特定情况下,必须将分配给一个ACL的一组文档分配给另一个ACL,而不管实例类型如何(在顶层)

ACL通过声明的批处理对文档进行快速获取,以优化读取文档

class Document {
}

class Image extends Document {
}

class ACL {
  Collection documents
  static mapping = {
     documents   lazy: false, batchSize: 100
  }

}
启用即时抓取并没有显著提高性能

已启用SQL日志记录来分析问题。我发现文档的记录是按预期获取的,但是对于每个文档,当使用for循环进行迭代时,会对文档集合中的每个元素执行附加的带有子类表的连接查询

ACL original = ACL.get(id)
for (doc in original.documents) {
  // Do whatever needs to be done
}
我假设触发此行为是因为显式类型未用于
doc
。我试过这个:

ACL original = ACL.get(id)
for (Document doc : original.documents) {
  // Do whatever needs to be done
}
不幸的是,这没有帮助


有没有办法告诉Grails它不应该从表中获取子类的数据,因为它不是必需的:只使用基类?

没有,没有办法告诉Hibernate(它实际上在做这件事,而不是Grails)这样做。如果需要这种类型的优化,则需要使用原始SQL,而不是HQL或基于GORM的查询

为了解释为什么这是不可能的,你需要从ORM的角度考虑这一点。在您在此介绍的域示例中,“文档”不会被保存,“图像”会被保存。具体的例子总是“图像”,而不是“文档”。为了生成文档列表,ORM不仅必须加载基类中的数据,还必须加载实现类中的数据。这是不可避免的。避免这种情况会创建一个类的实例,而该类不是域的有效表示形式

这是使用ORM必须支付的价格之一