【发布时间】:2014-02-03 12:05:03
【问题描述】:
我正在使用 PLAY 2.2.1、Ebean 构建一个 WebApp,并希望优化通过多对多关系关联到另一个实体的实体列表的获取。
更准确地说,我正在获取书籍列表:
@Entity
public class Book extends Model {
@Id
@Column(name="book_id")
public int bookId;
@ManyToMany
@JoinTable(name="book_author",
joinColumns={@JoinColumn(name="book_id", referencedColumnName = "book_id")},
inverseJoinColumns={@JoinColumn(name="author_id", referencedColumnName = "author_id")})
public List<Author> authors;
}
...每本书都与作者列表相关联:
@Entity
public class Author extends Model {
@Id
@Column(name="author_id")
public int authorId;
}
创建查询并获取其结果的代码是
Query<Book> queryBooks = Ebean.createQuery(Book.class);
queryBooks.where("...");
FutureList<Book> fLBooks = queryBooks.findFutureList();
if (fLBooks.isDone()){
List<Book> books = fLBooks.get();
}
FutureList 因为我想并行声明不同的查询。我需要访问所有书籍和所有作者,因此我必须遍历所有书籍及其所有作者:
for(Book b : books){
List<Author> authors = b.authors;
for (Author a : authors){
...
}
}
它可以工作,但是内部循环中的迭代非常慢,比分别查询表book、book_author 和author 慢得多。我想 Ebean 一次只取作者一个。
有更快的方法吗?
使用@ManyToMany(fetch=FetchType.EAGER) 不会改变检索速度。
更新 05.02.2014
我以这种方式创建查询:
Query<Book> queryBooks = Ebean.createQuery(Book.class);
FutureList<Book> fLBooks = queryBooks.fetch("authors", "*").where("...").findFutureList();
生成的 Ebean 查询是
select
t0.book_id c0,
t1.author_id c0
from book t0
left outer join book_author t1z_ on t1z_.book_id = t0.book_id
left outer join author t1 on t1.author_id = t1z_.author_id
where MATCH (t0.text) AGAINST ('...' IN BOOLEAN MODE) order by t0.book_id
好: Ebean 现在生成单个查询。
糟糕: 仍然比分别查询表 book、book_author 和 author 慢 20 倍。也许mysql查询优化器不起作用?
【问题讨论】:
-
那么你最初是如何得到书单的呢?
-
查看我的更新(创建查询并获取结果的代码)。
标签: database performance persistence ebean