Laravel:改进了透视查询

时间:2014-10-07 04:59:54

标签: laravel laravel-4

我成功查询了以下内容并创建了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));

如果有人能帮助我优化查询,那将非常棒。

1 个答案:

答案 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()的情况下手动分页结果,因此可能不希望您想要实现。

修改

你可能做的是:

  1. 您获得属于该类别的所有帖子(但实际上您只想对其中的10个进行分页)
  2. 为您想要的每个帖子显示它所属的所有类别。
  3. 要减少您应该使用的查询数量:

    $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