【问题标题】:Why do these 2 (similar?) MySQL queries vary so much in their execution times?为什么这 2 个(相似的?)MySQL 查询的执行时间差异如此之大?
【发布时间】:2012-04-12 16:51:27
【问题描述】:

我有表 playersplayers_to_teamsaccountsplayers_to_teamsplayersaccounts 有一个 FK。 players 有一个 FirstNameaccounts 有一个 NameFirstNameName 都已编入索引。

跑步

SELECT players_to_teams.id
FROM players_to_teams
INNER JOIN players
ON players.id = players_to_teams.player_id
ORDER BY players.FirstName

在 0.004 秒内执行。

SELECT players_to_teams.id
FROM players_to_teams
INNER JOIN accounts
ON accounts.id = players_to_teams.account_id
ORDER BY accounts.Name

执行时间超过 7 秒。

有 30,000 个帐户记录和 250,000 个玩家记录。

EXPLAINs 可以在这里找到:https://gist.github.com/2368906

这些查询不应该在相似的时间空间中执行吗?

【问题讨论】:

  • 你有几个账户?
  • 它与连接表的列或记录的数量(我不记得)有关。我记得不久前在数据库类中看到过这个概念。让我刷新一下思路。
  • 可能队伍中的 account_id 没有被编入索引?
  • @Rufinus - 我有一个错字。我有 30,000 条帐户记录
  • @kappa - account_id 在 player_to_team 中被索引(我认为)。你能仔细检查一下那个要点吗?

标签: mysql select indexing


【解决方案1】:

您较慢的查询需要一个临时表来对结果集进行排序,而另一个可以使用 FirstName 上的索引,从而避免一起排序。 (额外:使用索引;使用临时;使用文件排序)

您可以尝试强制对帐户进行索引,看看您是否可以超越优化的?

SELECT players_to_teams.id
FROM players_to_teams 
INNER JOIN accounts FORCE INDEX(Name)
ON accounts.id = players_to_teams.account_id
ORDER BY accounts.Name

另一种选择是使用直接连接重写查询,并首先列出帐户表。

我没有什么好的答案,为什么当帐户的行数少得多时,它目前首先选择 player_to_teams。

【讨论】:

【解决方案2】:

另一个可能有帮助的选项...我记得在某处读过...如果您在帐户 ID 和名称上都有一个索引作为单个索引(id,名称),那么引擎不必去返回原始数据记录以提取名称值,并可以直接从索引中提取它...从而节省读取匹配项的完整记录的时间。

【讨论】:

  • accounts 具有 id_name 复合索引。你是这么想的吗?
猜你喜欢
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 2017-12-24
  • 2018-06-18
  • 2019-09-13
  • 2014-06-20
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多