我无法急切地加载子类的多态父级。包含声明似乎没有区别。
儿童班:
@BelongsToPolymorphic(
parents = {ParentRequest.class},
typeLabels = {"parent_request"})
public class Child extends Model {
}
父类:
public class ParentRequest extends Model {
}
查询应该急切地返回child + parent:
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毫秒。
非常感谢任何见解或帮助。
注意:我知道Child只有一个父母。在不久的将来它会有几个。
修改 由于某些原因,反转查询产生了更快的结果。也就是说,如果我搜索ParentRequest并包含Child,而不是寻找Children并包括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);
答案 0 :(得分:1)
我写了一个简单的测试和 启用日志记录 :
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毫秒是相当快的,&#34;瓶颈&#34;在哪里。
您需要做的是看到差异是加载更大的数据集。
此外,请记住,加载的数据越多,分配的堆空间就越多。最终include()
方法解决了N + 1问题(http://javalite.io/lazy_and_eager),但这并不意味着您的应用程序会更快。您需要进行实验,并决定是否最好将其用于您的案例。
要点:
如果使用include()
方法,则对数据库的调用次数会减少,但会分配更多RAM。您可以自行决定是否更快地使用您的应用。