Mysql Laravel Eloquent take()在大型数据集中速度非常慢或内存耗尽

Mysql Laravel Eloquent take()在大型数据集中速度非常慢或内存耗尽,mysql,laravel,eloquent,limit,laravel-collection,Mysql,Laravel,Eloquent,Limit,Laravel Collection,我有多对多的关系,如: class Game extends Model { public function players() { return $this->belongsToMany('App\Player'); } } 我有500k+游戏玩家条目,创建外键 当我使用limit=10运行时,需要很长时间才能得到结果,甚至内存耗尽: if ($request->filled('limit') && $request->

我有多对多的关系,如:

class Game extends Model
{
    public function players()
    {
        return $this->belongsToMany('App\Player');
    }
}
我有500k+游戏玩家条目,创建外键

当我使用
limit=10运行时,需要很长时间才能得到结果,甚至内存耗尽:

if ($request->filled('limit') && $request->limit > 0) {
    return response(Game::findOrFail($id)->players->take($request->limit), 200);
} else {
    return response(Game::findOrFail($id)->players, 200);
}

我应该改用SQL限制吗?我该怎么做呢?

您向数据库询问所有相关记录,然后在PHP端对它们进行过滤,然后将它们全部加载到内存中。由于您只需要某些记录,因此应向数据库询问这些记录:

Game::findOrFail($id)->players()->take($request->limit)->get()

这将使用关系方法查询数据库,并且只获取有限的一组记录。当使用动态属性
$game->players
时,您正在将整个关系加载到一个集合中。

您正在向数据库请求所有相关记录,然后在PHP端对它们进行过滤,然后将它们全部加载到内存中。由于您只需要某些记录,因此应向数据库询问这些记录:

Game::findOrFail($id)->players()->take($request->limit)->get()

这将使用关系方法查询数据库,并且只获取有限的一组记录。使用动态属性
$game->players
时,您正在将整个关系加载到一个集合中。

如果要检索大量数据,您可以使用两种方法来迭代结果:


  • 如果要检索大量数据,可以使用两种方法来迭代结果:


  • 谢谢,不知道括号有多大区别。谢谢,不知道括号有多大区别。