MySQL 多重连接速度慢

标签 mysql sql join

我有一个具有以下结构的表:

db structure

我的所有主键都是正确的,每个 int 和日期列都有一个索引,player_groups 中的 (playerId, groupId) 是一个唯一索引。所有表都使用 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 ON playerkills.serverId = s.serverId ORDER BY date DESC LIMIT 300;/p>

在我自己的机器上的性能,它有很多资源:

  • 查询 #1:0.0016 秒
  • 查询 #2:1.3050 秒

实时数据库主机上的性能,资源少得多:

  • 查询 #1:0.046 秒
  • 查询 #2:1.297 秒

我担心某些东西会严重影响性能,因为它在没有任何 JOIN 语句的情况下工作正常。 任何人都可以对此有更多的了解吗?

ps(编辑)。可能还需要补充一点:该数据库实时更新,每隔几秒更新一次,因此查询结果无法像静态数据查询那样缓存。

编辑 2: 对静态版本(在 localhost 上)的分析给了我这张图片:

db profile

EXPLAIN 的输出:

db explain

最佳答案

这是子选择可能对您的事业有所帮助的情况之一。与其将所有这些表格连接到完整的 playerkills 表格,您可以子选择最后 300 次玩家击杀,然后基于此加入。所以像这样:

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 多重连接速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20079372/

相关文章:

c# - SQL Server 存储过程在网络集群中执行得更好吗?

mysql - 根据其中一个表中特定列中的最大值返回 JOIN 结果

mysql 查询表连接

mysql - 使用 filesort 按 MySQL 中的日期时间列排序

sql - 如何在 SQL Server Express 中安排脚本(无需 SQL Server 代理)?

mysql - 在具有不同类型交易的sql连接交易表中

java - 在 Flink SQL Windows 中使用带有延迟的事件时间

java - 在 Java 中显示列表与在 Python 中一样优雅

mysql命令行垂直输出

mysql - 在 mySQL 中选择不同三元组的补集