繁体   English   中英

ActiveJDBC渴望加载多态父对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM