【发布时间】:2023-03-10 21:50:01
【问题描述】:
我需要挑选出用户当前所在的所有团队,这是我的 Eloquent 代码:
$teams = Team::orderBy('created_at', 'desc')->get()->filter(function($team) use ($user)
{
return $team->inTeam($user);
});
团队的花名册是用户 ID 数组,以字符串形式存储在数据库中。
这是 inTeam 函数:
public function inTeam($user)
{
$id = $user->id;
$players = $this->getPlayers();
foreach ($players as $p)
{
if (is_null($p)) continue;
if ($p == $id) return true;
}
return false;
}
每当加载包含此代码的页面时,我的服务器 CPU 使用率在 apache2 上飙升至约 60%+,在 mysqld 上飙升至约 30%,我无法弄清楚原因。在 Team 模型上使用 filter() 是我发现的最简洁的方式来做我需要的事情,它只会导致问题,甚至在足够多的用户加载页面时使网站停止。
有什么方法可以优化过滤,或者我需要重组我的数据库保存名册信息的方式吗?
编辑:我更新了我的代码以使用 FIND_IN_SET 并设法将 CPU 时间从 8 秒缩短到 5 秒。然而,仍然不理想。
$teams = Team::orderBy('id', 'desc')->whereRaw("FIND_IN_SET(" . $user->id . ", players_list)")->get();
我不知道如何为此规范化我的数据库,因为 players_list 列的长度根据 Event 与 Team 绑定的不同,因此以逗号分隔的字符串。
【问题讨论】:
-
如您所见,这很糟糕。规范化你的数据库并在那里做。现在,使用
find_in_set- dev.mysql.com/doc/refman/5.5/en/… 它将使用1,5,10字符串完成这项工作。也读这个stackoverflow.com/questions/27898953/… -
我已经更新了我的帖子,以反映切换到
FIND_IN_SET这有点帮助。我不知道如何为此规范化我的数据库,因为Event与Team绑定的players_list列的长度不同,因此用逗号分隔字符串。 -
你正在做的列 FIND_IN_SET 是索引吗?
-
@Kairu 只需为
teams和players之间的 mm 关系创建一个数据透视表 - 这是您以正常形式处理多对多关系的方式,而不是逗号分隔的 id。跨度>
标签: php eloquent filtering cpu-usage