[英]ActiveJDBC eager loading of Polymorphic Parents
我无法急于加载子类的多态父类。 包含语句似乎没有什么区别。
儿童班:
@BelongsToPolymorphic(
parents = {ParentRequest.class},
typeLabels = {"parent_request"})
public class Child extends Model {
}
家长班:
public class ParentRequest extends Model {
}
急切返回子代+父代的查询:
List<Child> children = Child.where("... limit 500").include(ParentRequest.class);
children.size(); //this gives me 500
children.cachedParents.size(); //this gives me 0;
最终,我试图加快以下操作:
for (Child child : children) {
ParentRequest pr = child.parent();
// lots of pr.getString("parent_field");
...
}
我已经进行了这些操作的基准测试,无论是否在Child.where()方法上使用.include(ParentRequest.class),上述操作似乎都需要67毫秒左右。
任何见解或帮助,我们将不胜感激。
注意:我知道孩子只有一个父母。 在不久的将来它将有几个。
编辑:由于某些原因,反向查询产生了更快的结果。 也就是说,如果我搜索ParentRequest并包含Child,则无需查找Child并包含ParentRequest,该操作要快得多。 请注意,我专门做了一个findBySql来将子表加入结果中的parent_request表。 下面,我保留了查询的细节。
List<ParentRequest> parents = ParentRequest.findBySQL("SELECT child.*, parent_requests.* " +
"FROM child JOIN parent_requests ON child.parent_id=parent_requests.id WHERE " +
"RAND()<=? AND (child.metersToA BETWEEN ? AND ?) " +
" AND (child.metersToB BETWEEN ? AND ?) limit ?",
decimation_value,
minDistanceToA, maxDistanceToA ,
minDistanceToB, maxDistanceToB,
MAX_POINTS).include(Child.class);
我编写了一个简单的测试并启用了日志记录 :
Article article = Article.findById(1);
article.add(Comment.create("author", "tjefferson", "content", "comment 1"));
article.add(Comment.create("author", "tjefferson", "content", "comment 2"));
LazyList<Comment> comments = Comment.where("author = ?", "tjefferson").include(Article.class);
System.out.println(comments.size());// does loading of data, prints 2
Article parent1 = comments.get(0).parent(Article.class); // does not generate DB query
Article parent2 = comments.get(1).parent(Article.class); // does not generate DB query
assert (parent1 == parent2); // true
执行此代码会将以下内容记录到控制台:
SELECT * FROM comments WHERE author = ?", with parameters: <tjefferson>, took: 1 milliseconds
SELECT * FROM articles WHERE id IN (?)", with parameters: <1>, took: 1 milliseconds
如您所见,对数据库只有两个查询。 另外,您提到的行:
children.cachedParents.size(); //this gives me 0;
将不会编译,因为LazyList
没有成员cachedParents
。
如果您在这种情况下遍历孩子,并得到像这样的父母:
child.parent(Parent.class)
,因为对象被缓存在内存中,所以不会有数据库查询到数据库。
该框架按预期工作。 无论是否include()
,数据集大小的计时原因都是相同的。 67毫秒相当快,而“瓶颈”在其他地方。
您需要做的是看到差异是加载更大的数据集。
此外,请记住,加载的数据越多,分配的堆空间就越大。 最终include()
方法解决了N + 1问题( http://javalite.io/lazy_and_eager ),但这并不意味着您的应用程序会更快。 您需要进行试验,并确定是否适合您的情况。
摘要:如果使用include()
方法,则对数据库的调用将减少,但将分配更多的RAM。 您可以自行决定应用程序是否更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.