我有一张桌子,结构如下:
我的主键都是正确的,每个int&date列都有一个索引,(playerId, groupId)
中的player_groups
是唯一的索引。所有表都在使用InnoDB,您看到的关系也是InnoDB中的引用。
完整的数据库源,包含数据,与下面我将演示的示例大致相似:https://www.dropbox.com/s/kzf89occlq4legy/bf4_performance.sql
查询:
查询1:SELECT * FROM playerkills ORDER BY date DESC LIMIT 300;
查询2:SELECT p.playerName AS player, p2.playerName AS target, w.weaponName AS weapon, date, headshot, s.serverName AS server FROM playerkills JOIN players p ON playerkills.playerId = p.playerId JOIN players p2 ON playerkills.targetId = p2.playerId JOIN weapons w ON playerkills.weaponId = w.weaponId JOIN servers s ON playerkills.serverId = s.serverId ORDER BY date DESC LIMIT 300;
我自己的机器上的性能,它有很多资源:
查询1:0.0016秒
查询2:1.3050秒
实时数据库主机上的性能,该主机的资源少得多:
查询1:0.046秒
查询2:1.297秒
恐怕有些东西对性能影响很大,因为它在没有任何JOIN
语句的情况下运行良好。
有谁能再解释一下吗?
ps(编辑)。还可能需要添加一些重要信息:该数据库正在实时更新,每几秒钟更新一次,因此查询结果不能像对静态数据的查询那样进行缓存。
编辑2:静态版本(onlocalhost
)上的分析为我提供了以下图片:EXPLAIN
的输出:
最佳答案
这是其中一种情况下,一个子选择可能有助于你的事业。与其将所有这些表都加入到完整的player kills表中,不如重新选择最后300个playerkills,然后基于此加入。比如说:
SELECT
p.playerName AS player,
p2.playerName AS target,
w.weaponName AS weapon,
pk.date AS date,
pk.headshot AS headshot,
s.serverName AS server
FROM
(SELECT * FROM playkills ORDER BY date DESC LIMIT 300) AS pk
JOIN players p
ON pk.playerId = p.playerId
JOIN players p2
ON pk.targetId = p2.playerId
JOIN weapons w
ON pk.weaponId = w.weaponId
JOIN servers s
ON pk.serverId = s.serverId
关于mysql - MySQL多次连接缓慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20079372/