0

我无法急切地加载子类的多态父类。include 语句似乎没有任何区别。

儿童班:

@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,则操作会快得多,而不是查找 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);
4

1 回答 1

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;

不会编译,因为 aLazyList没有成员cachedParents

如果你在这种情况下遍历孩子,并得到一个像这样的父母:

child.parent(Parent.class)

,将不会有对数据库的数据库查询,因为对象缓存在内存中。

该框架按预期工作。无论有无include()数据集的大小,您的时间都相同的原因。67 毫秒相当快,“瓶颈”在别处。

您需要做的是加载更大的数据集以查看差异。

此外,请记住,加载的数据越多,分配的堆空间就越多。最终,该include()方法解决了 N+1 问题(http://javalite.io/lazy_and_eager),但这并不意味着您的应用程序会更快。您需要进行试验,并决定是否最好在您的情况下使用它。

总结:如果使用include()方法,对数据库的调用会更少,但会分配更多的 RAM。由您决定它是否对您的应用程序更快。

于 2016-08-24T18:34:25.480 回答