【问题标题】:Laravel Eloquent take() is very slow or memory exhausted in large datasetLaravel Eloquent take() 在大型数据集中非常慢或内存耗尽
【发布时间】:2021-03-27 20:49:11
【问题描述】:

我有一个多对多的关系:

class Game extends Model
{
    public function players()
    {
        return $this->belongsToMany('App\Player');
    }
}
class Player extends Model
{
    public function games()
    {
        return $this->belongsToMany('App\PlayerGame');
    }
}

我有 500k+ game_player 条目,已创建外键。

当我使用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 限制吗?又该如何做好呢?

【问题讨论】:

    标签: mysql laravel eloquent limit laravel-collection


    【解决方案1】:

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

    1. Chunking
    2. Cursors

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 谢谢,不知道括号有这么大的区别。
      猜你喜欢
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2019-09-09
      • 2020-08-30
      • 1970-01-01
      相关资源
      最近更新 更多