我需要优化一个查询,以获得永远需要的排名(查询本身有效,但我知道这很糟糕,我刚刚用大量记录尝试过它,它给出了超时)。
我将简要解释模型。我有 3 张桌子:player、team 和 player_team。我有球员,他们可以属于一个球队。听起来很明显,球员存储在球员表中,球队存储在球队中。在我的应用程序中,每个玩家都可以随时切换团队,并且必须保留日志。但是,在给定时间,一名球员被认为只属于一个球队。玩家的当前团队是他加入的最后一个团队。
我认为球员和球队的结构并不相关。我每个都有一个 id 列 PK。在 player_team 我有:
id (PK)
player_id (FK -> player.id)
team_id (FK -> team.id)
现在,每支球队都会为每个加入的球员分配一个积分。所以,现在,我想得到前 N 支拥有最多球员的球队的排名。
我的第一个想法是首先从 player_team 获取当前玩家(即每个玩家的最高记录;该记录必须是玩家当前的团队)。我没有找到一个简单的方法来做到这一点(尝试 GROUP BY player_team.player_id HAVING player_team.id = MAX(player_team.id),但这并没有削减它。
我尝试了一些不起作用的查询,但设法让它工作。
SELECT
COUNT(*) AS total,
pt.team_id,
p.facebook_uid AS owner_uid,
t.color
FROM
player_team pt
JOIN player p ON (p.id = pt.player_id)
JOIN team t ON (t.id = pt.team_id)
WHERE
pt.id IN (
SELECT max(J.id)
FROM player_team J
GROUP BY J.player_id
)
GROUP BY
pt.team_id
ORDER BY
total DESC
LIMIT 50
正如我所说,它可以工作,但看起来很糟糕,性能更差,所以我确信一定有更好的方法。有人对优化这个有什么想法吗?
顺便说一句,我正在使用mysql。
提前致谢
添加解释。(抱歉,不知道如何正确格式化)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t ALL PRIMARY NULL NULL NULL 5000 Using temporary; Using filesort
1 PRIMARY pt ref FKplayer_pt77082,FKplayer_pt265938,new_index FKplayer_pt77082 4 t.id 30 Using where
1 PRIMARY p eq_ref PRIMARY PRIMARY 4 pt.player_id 1
2 DEPENDENT SUBQUERY J index NULL new_index 8 NULL 150000 Using index