我有以下关系:
工作有很多角色。
public function roles()
{
return $this->hasMany(Role::class);
}
角色通过班次有很多班次和作业。
public function shifts()
{
return $this->hasMany(Shift::class);
}
public function assignments()
{
return $this->hasManyThrough(Assignment::class, Shift::class);
}
Shift有许多作业。
public function assignments()
{
return $this->hasMany(Assignment::class);
}
我需要计算具有特定状态的所有作业,让我们说"已批准"。这些计数导致我的申请进展非常缓慢。以下是我一直在做的事情:
foreach ($job->roles as $role){
foreach ($role->shifts as $shift) {
$pendingCount = $shift->assignments()->whereStatus("Pending")->count();
$bookedCount = $shift->assignments()->whereIn('status', ["Booked"])->count();
}
}
我确信必须有更好,更快的方式。其中一些查询耗时超过30秒。有数十万个任务,我知道这会影响性能。如何加快这些查询?
答案 0 :(得分:1)
你在这里遇到了N + 1问题几次。您希望通过作业延迟加载嵌套赋值,然后您可以访问该关系,并且对返回的集合而不是查询构建器执行<type 'unicode'>
[ 24-Янв-17 07:24 ]
<type 'str'>
[ 24-???-17 07:24 ]
和where()
调用,这就是您必须使用{我的示例中代替whereIn()
,因为集合不会自动解决此约束:
where('status', "Pending")
这对你来说应该快得多。
<强>更新强>
您甚至可以更进一步,并将结果映射并将结果存储在角色的属性中:
whereStatus("Pending")