我的游戏服务器上有一个巨大的瓶颈,用于存储当前排行榜的以下查询。
我目前仅每 5 分钟通过 cron 调用一次此查询,但希望将其优化到足以每分钟或在需要时调用。
查询耗时 30 秒,目前只有约 2000 名用户和 7000 场比赛(存储在 Games 和 TopPlayerScores 中)。恐怕只会越来越严重!!请帮帮我溢出-克诺比!你是我唯一的希望!
SET @rank=0;
INSERT INTO Board (TopScorePKID, GamePKID, UserPKID, UniquePlayerID, PlayerName, TopPlayerScore, Position, Date)
(SELECT bad.ID AS TopScorePKID, bad.GamePKID, bad.UserPKID, bad.UniquePlayerID, bad.PlayerName, bad.TopPlayerScore, @rank:=@rank+1 AS Position, bad.Date
FROM (
SELECT g.GamePKID, g.TopPlayerScore, l.ID, l.UserPKID, u.UniquePlayerID, u.PlayerName, (l.Date) AS Date
FROM Games g, TopPlayerScores l, UserDetails u
WHERE l.GamePKID = g.GamePKID
AND u.UserPKID = l.UserPKID
AND u.SECRET_DETAIL = 0
AND g.TopPlayerScore >= (SELECT DISTINCT k.TopPlayerScore AS Highest
FROM Games k, TopPlayerScores t
WHERE t.UserPKID = l.UserPKID
AND k.GamePKID = t.GamePKID
ORDER BY k.TopPlayerScore DESC
LIMIT 1)
GROUP BY l.UserPKID
ORDER BY g.TopPlayerScore DESC, Date ASC)
AS bad);
请有人帮忙!!我应该把它分解成视图吗?还是使用内连接关键字?最好的方法是什么?
非常感谢您甚至看到这个烂摊子:D!
更新 1.0: 解释扩展结果:
id select_type 表类型 possible_keys key key_len ref rows 已过滤 Extra 1 PRIMARY ALL NULL NULL NULL NULL 1521 100.00 2 DERIVED l ALL NULL NULL NULL NULL 6923 100.00 使用临时;使用文件排序 2 DERIVED u eq_ref PRIMARY PRIMARY 4 DBNAME.l.UserPKID 1 100.00 使用 where 2 DERIVED k eq_ref PRIMARY PRIMARY 4 DBNAME.l.GamePKID 1 100.00 使用 where 3 相关子查询 t ALL NULL NULL NULL NULL 6923 100.00 使用 where;使用临时的;使用文件排序 3 DEPENDENT SUBQUERY g eq_ref PRIMARY PRIMARY 4 DBNAME.t.GamePKID 1 100.00 使用 where
更新 2.0: 查询表的有限模式
使用游戏存储游戏分数和其他有关游戏的信息
`Games` (
`GamePKID` int(11) NOT NULL AUTO_INCREMENT,
`TopPlayerScore` int(11) NOT NULL,
`OTHER_MISC_STUFF_REMOVED` int(11) NOT NULL
PRIMARY KEY (`GamePKID`)
)
使用以下内容将用户链接到游戏并存储时间/日期
`TopPlayerScores` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`UserPKID` int(11) NOT NULL,
`GamePKID` int(11) NOT NULL,
`Date` datetime NOT NULL,
PRIMARY KEY (`ID`)
)
用于存储每个唯一的玩家
`UserDetails` (
`UserPKID` int(11) NOT NULL AUTO_INCREMENT,
`UniquePlayerID` char(40) NOT NULL,
`PlayerName` char(96) NOT NULL,
`SECRET_DETAIL` tinyint(1) NOT NULL DEFAULT '0',
`isPlayer` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`UserPKID`)
)