使用雄辩的

时间:2017-01-24 21:32:13

标签: laravel eloquent laravel-5.1

我有以下关系:

工作有很多角色。

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秒。有数十万个任务,我知道这会影响性能。如何加快这些查询?

1 个答案:

答案 0 :(得分:1)

你在这里遇到了N + 1问题几次。您希望通过作业延迟加载嵌套赋值,然后您可以访问该关系,并且对返回的集合而不是查询构建器执行<type 'unicode'> [ 24-Янв-17 07:24 ] <type 'str'> [ 24-???-17 07:24 ] where()调用,这就是您必须使用{我的示例中代替whereIn(),因为集合不会自动解决此约束:

where('status', "Pending")

这对你来说应该快得多。

<强>更新

您甚至可以更进一步,并将结果映射并将结果存储在角色的属性中:

whereStatus("Pending")