Grails应用程序维护有关已保存文档的数据。
使用名为Document
的基本域类为域类创建简单的域类层次结构。
当前使用每个子类的表方法。它不是最有效的,但是现在还可以。
对文档的访问由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 Angular 考虑这一点。在您的网域示例中,此处未显示“文档”,而是“图像”。具体实例始终是“图像”实例,而不是“文档”实例。为了合并文档列表,ORM不仅必须加载基类中的数据,还必须加载实现类中的数据。这是无法避免的。避免这种情况将创建不是该域的有效表示形式的类的实例。
这是使用ORM必须支付的价格之一。
关于hibernate - 优化:渴望获取基域类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25886488/