我花了很长时间寻找这个问题的解决方案:
假设我们有 2 个表,第一个表是 Clients 表,第二个表是 ClientAssignment 表: ClientAssignment 表与 Clients 表相关:
public function assignment()
{
return $this->hasOne(ClientAssignment::class, 'client_id');
}
现在,当我想计算有多少 ClientAssignment 有客户端时,我会这样做:
$users =[1,2,3,4 .....]
$userAssignments = array();
foreach ($users as $user) {
$user_assignments = Client::whereHas('assignment', function ($query) use ($user) {
$query->where('assigned_id', $user);
});
$ua['user_id'] = $user;
$ua['count'] = $user_assignments->count();
array_push($userAssignments, $ua);
}
该代码运行良好,但在具有 80k 客户端的相对较小的表上,它的性能和查询执行时间达到了约 20 秒以上, 我的问题是否可以用另一种方法来做同样的事情,但性能和查询执行时间最低?
最佳答案
根据你的帖子,我认为
Client --- hasOne ----> ClientAssignment <----- hasMany ---- User
[client_id, assigned_id]
因此User
可以通过ClientAssignment
拥有许多Client
,
但是,您的 client_id
和 assigned_id
均位于 client_assignment
表中。所以你不能使用hasManyThrough
,这就像一个数据透视表;
幸运的是,您可以直接计算 client_id
并获取 assigned_id
作为 user_id
只需使用此数据透视表即可。
查询如下(使用distinct(client_id)
来防止脏记录):
ClientAssignment::whereIn('assigned_id', $users)
->groupBy('assigned_id')
->select('assigned_id AS user_id',
DB::raw('COUNT(DISTINCT(client_id)) AS count'))
->get()->toArray();
并添加signed_id
索引以提高性能。
$table->index('assigned_id');
关于php - 需要关系数的意见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59824564/