Laravel 高效查询状态为0的文章所属关联用户记录的方法
高效获取状态为0的文章关联用户的实现方法
你现在用循环逐次查询用户的写法,存在典型的N+1查询性能问题:假设查到N条状态为0的文章,会先执行1次文章查询SQL,再对每篇文章单独执行1次用户查询SQL,总查询次数随文章数量线性增长,文章越多查询效率越低。
Laravel框架自带的关联预加载功能可以完全解决这个问题,常用的实现方式有两种:
方式一:查询文章时直接预加载关联用户
这种方式不需要修改现有模型定义,复用你已经写好的Article模型的user关联即可。框架会自动执行仅2次SQL:第一次查出所有状态为0的文章,第二次根据文章集合里的所有user_id,一次性批量查出对应的全部用户记录,自动把用户实例匹配到对应文章上,全程不会产生额外的单条查询。
对应代码:
// 查状态为0的文章,同时预加载关联的user信息 $articles = Article::whereStatus(0)->with('user')->get(); // 后续遍历直接拿对应用户即可,无需触发新的数据库查询 foreach ($articles as $article) { $user = $article->user; }
如果不需要用户的全部字段,还可以指定要查询的关联字段,减少不必要的数据传输:
// 仅查询用户的id、username字段 $articles = Article::whereStatus(0)->with('user:id,username')->get();
方式二:直接批量获取去重后的目标用户
如果你不需要在文章实例上挂载用户信息,只是想要拿到所有发布过状态为0的文章的用户列表,可以直接通过关联反向查询,一次拿到所有去重后的用户记录。这种写法需要你的User模型定义好和Article的反向hasMany关联:
// User模型中定义的反向关联 public function articles() { return $this->hasMany(Article::class, 'user_id'); }
关联定义好之后,就可以直接查询符合条件的用户:
$users = User::whereHas('articles', function ($query) { $query->where('status', 0); })->get();
这种方式下哪怕有10篇文章都是同一个用户发布的,也只会返回1条对应用户的记录,不需要后续再手动去重。
内容的提问来源于stack exchange,提问作者Valentine
相关产品推荐
相关产品推荐

