我成功查询了以下内容并创建了130个查询,我希望对其进行优化并减少查询次数,我已按照以下方式设置了模型和控制器。
发布模式
class Post extends Eloquent {
public function Categories () {
return $this->belongsToMany('Category', 'category_post');
}
}
类别模式
class Category extends Eloquent {
public function posts () {
return $this->belongsToMany('Post', 'category_post');
}
}
并且在Controller中,我使用以下查询,以下查询的作用是,根据类别ID查询结果。
$category = Category::with('posts')->where('id','=',$id)->paginate(10)->first();
return Response::json(array('category' => $category));
如果有人能帮助我优化查询,那将非常棒。
答案 0 :(得分:0)
你错了,它不会创建130个查询。
它将创建以下3个查询:
select count(*) as aggregate from `categories` where `id` = '5';
select * from `categories` where `id` = '5' limit 10 offset 0;
select `posts`.*, `posts_categories`.`category_id` as `pivot_category_id`, `posts_categories`.`post_id` as `pivot_post_id` from `posts` inner join `posts_categories` on `posts`.`id` = `posts_categories`.`post_id` where `posts_categories`.`category_id` in ('5');
但问题是你想要分页到底是什么。现在您对类别进行了分页并且它没有多大意义,因为只有一个类别具有选定的$id
。
您可能希望得到的是:
$category = Category::where('id','=',$id)->first();
$posts = $category->posts()->paginate(10);
这将再次创建3个查询:
select * from `categories` where `id` = '5' limit 1;
select count(*) as aggregate from `posts` inner join `posts_categories` on `posts`.`id` = `posts_categories`.`post_id` where `posts_categories`.`category_id` = '5';
select `posts`.*, `posts_categories`.`category_id` as `pivot_category_id`, `posts_categories`.`post_id` as `pivot_post_id` from `posts` inner join `posts_categories` on `posts`.`id` = `posts_categories`.`post_id` where `posts_categories`.`category_id` = '5' limit 10 offset 0;
如果你想改进它,你可能不需要在这种情况下使用Eloquent并使用join
- 但是它值得吗?您现在需要在没有paginate()
的情况下手动分页结果,因此可能不希望您想要实现。
修改强>
你可能做的是:
要减少您应该使用的查询数量:
$category = Category::where('id','=',$id)->first();
$posts = $category->posts()->with('categories')->paginate(10);
要显示它,您应该使用:
foreach ($posts as $p) {
echo $p->name.' '."<br />";
foreach ($p->categories as $c) {
echo $c->name."<br />";
}
}
它应该将您的号码查询从130
降低到4