优化查询-急切加载占用太多内存


Optimizing Queries - Eager loading takes too much memory

我有以下表格:

  • 用户(约1.000行)
  • 风扇(约100000行)-一个用户有多个风扇,一个风扇属于一个用户
  • 点赞(约100000行-一个用户有多个点赞,一个点赞属于一个用户

现在我想要一张有的桌子

  • 用户名
  • 风扇数量
  • 点赞数

这是一个大表,我使用jQueryDataTable将其与pagnition一起使用,但这是关于服务器端的。

我已经建立了我所有的关系,并摆出了桌子:

$users = User::get();
foreach ($users as $user) {
echo $user->name;
echo $user->fans()->count();
echo $user->likes()->count();
}

这是很多查询,我想优化。我的第一次尝试是使用Eager Loading。

$users = User::with('fans', 'likes')->get();

但这似乎对服务器内存非常不利。在我的本地环境中,php脚本的内存大小为16 MB。它总是试图分配更多。

这正常吗?简单地给脚本更多内存是最好的解决方案吗?我还能如何优化我的查询?

如果你只想统计记录的数量,那么获取所有记录只是为了统计它们是没有意义的,现在你可以获得201000行。您应该添加:

public function fansCountRelation()
{
    return $this->hasOne('Fan')->selectRaw('user_id, count(*) as count')
        ->groupBy('user_id');
}

public function likesCountRelation()
{
    return $this->hasOne('Like')->selectRaw('user_id, count(*) as count')
        ->groupBy('user_id');
}
public function getLikesCountAttribute()
{
    return $this->likesCountRelation ?
        $this->likesCountRelation->count : 0;
}
public function getFansCountAttribute()
{
    return $this->fansCountRelation ?
        $this->fansCountRelation->count : 0;
}

到您的User模型,现在您将只获得1000个用户行+粉丝和点赞的聚合数据。

现在你可以使用:

$users = User::with('fansCountRelation', 'likesCountRelation')->get();
foreach ($users as $user) {
    echo $user->name;
    echo $user->likes_count;
    echo $user->fans_count;
}

然而,如果你真的需要它,你应该重新考虑。正常使用1000行太多了。如果您将其用于导出目的,这很好,但如果您仅在管理面板中显示它,则应该使用分页。

如果这需要花费大量时间,您应该确保为fanslikes表的user_id列提供索引。它应该会大大加快您的查询速度。