You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9中从Eloquent关联获取唯一用户列表的优化方案

Laravel 9 关联用户唯一列表查询优化

方法一:反向关联直接查询(推荐,数据库层面处理,性能最优)

如果你的User模型中已经定义了与Item的关联关系(比如belongsToMany或hasMany),可以直接从User模型出发,过滤出关联了type为user的Item的用户,数据库会自动处理去重:

// 假设User模型的关联定义示例(根据实际关联类型调整):
// public function items()
// {
//     return $this->belongsToMany(Item::class);
// }

$uniqueUsers = User::whereHas('items', function ($query) {
    $query->where('type', 'user');
})->get();

这种方式不需要加载所有Item数据,直接在数据库层面完成过滤和去重,避免内存冗余,性能最佳。

方法二:集合方法简化现有逻辑(无需循环)

如果业务上必须先获取Item集合,可以用Laravel集合的flatMap方法替代手动循环,代码更简洁高效:

$items = Item::where('type', 'user')->with('users')->get();
$uniqueUsers = $items->flatMap(fn($item) => $item->users)->unique();

flatMap会自动将每个Item的users集合展开为一维集合,再调用unique()去重,比原代码的循环merge更简洁。

方法三:通过关联表直接查询

也可以直接通过关联表的JOIN操作,在数据库层面获取去重后的用户列表,适合不想依赖反向关联的场景:

// 注意:表名和关联字段需根据你的实际数据库结构调整
$uniqueUsers = Item::where('type', 'user')
    ->join('item_user', 'items.id', '=', 'item_user.item_id') // 关联中间表
    ->join('users', 'users.id', '=', 'item_user.user_id')
    ->select('users.*')
    ->distinct()
    ->get();

原代码的冗余问题说明

原代码中已经用with('users')预加载了关联数据,但循环里又调用$item->users()->get(),这会触发N+1查询(每个Item都单独查一次用户),完全浪费了预加载的作用。哪怕不优化结构,也应该直接使用$item->users(预加载的集合)而非$item->users()->get()。

内容的提问来源于stack exchange,提问作者party-ring

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:01:11