2014-10-07 165 views
0

我成功查询以下并创建130个查询,我想优化它并减少查询数量,我已经按照以下方式设置了模型和控制器。Laravel:改进的枢轴查询

邮莫代尔

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'); 
    } 
} 

,并在控制器中,我使用下面的查询,做什么下面的查询,查询基于类别ID结果。

$category = Category::with('posts')->where('id','=',$id)->paginate(10)->first(); 
return Response::json(array('category' => $category)); 

如果任何人都可以给我一只手来优化查询,那真是太棒了。

回答

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; 

如果你想改善它,你可能会需要不使用雄辩在这种情况下,并使用join - 但它值得吗?您现在需要手动对结果进行分页,而不使用paginate(),因此可能不会希望您想实现。

编辑

什么你可能做的是:

  1. 你属于类别的所有讯息(但事实上,你想分页只有其中的10)
  2. 每个发布你想要显示它所属的所有类别。

为了降低查询的号码,你应该使用:

$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

+0

降低你的电话号码查询4我得到以下信息![1] [1]:h ttp://i.stack.imgur.com/T7CW4.png – Yoosuf 2014-10-07 07:33:31

+0

@Yoosuf只有3个首先连接到上面。您应该查看代码的其余部分,因为其他查询可能由其他代码执行。您还可以显示更多代码(编辑您的问题)以显示此内容。你是否显示每个帖子的类别?正如我向你展示的第一个问题是你使用的分页,你不需要10条记录,但所有这些(可能你有100个职位) – 2014-10-07 07:42:01

+0

@Yoosuf我编辑了我的答案 – 2014-10-07 07:48:30