【问题标题】:Optimizing MySQL Join and Group By with intermediate table使用中间表优化 MySQL Join 和 Group By
【发布时间】:2016-01-09 00:17:21
【问题描述】:

简化但我有三个表:

  • 用户(user_id、team_id)
  • 结果(user_id,结果)
  • user_signups (user_id, team_id, event_id)

results.user_id 是外键。

表格中有大量行。如果我这样做了

select sum(result)
from results
inner join users on users.id = results.user_id
group by team_id

速度很快。 “解释”的结果有 150k 行,用户有 1 行。

如果我这样做

select sum(result)
from results
inner join user_signups on user_signups.user_id = results.user_id
where event_id = 1
group by team_id

它非常慢(从 1 秒到 14 秒)。 “解释”的结果有 28 行,user_signups 有 5345 行。

我尝试过的事情:

user_signups 上 event_id 和 user_id 的唯一索引。

user_signups 上 event_id、user_id、team_id 的索引。

改写为

select sum(result)
from results
inner join (select * from user_signups where event_id = 1) user_signups on user_signups.user_id = results.user_id
group by team_id

改写为

select sum(result)
from results
inner join users on users.id = results.user_id
inner join user_signups on user_signups.user_id = users.id
where event_id = 1
group by user_signups.team_id

还有其他建议吗?

【问题讨论】:

  • 请确定每个表上的现有索引,并建议您在问题中显示解释计划结果,示例数据和预期结果也会有所帮助(也许设置一个 sqlfiddle?sqlfiddle.com)
  • 去阅读一些关于mysql查询优化的其他问题。通常,当他们没有架构的详细信息和解释计划时,他们会被否决或回答不佳。
  • 请为每张桌子提供SHOW CREATE TABLE

标签: mysql query-optimization


【解决方案1】:

通过对 team_id 进行分组,我假设您希望 results 中的每条记录都有一行。

这就是你要找的吗?

SELECT *, sum(result) FROM results
LEFT JOIN users ON (users.user_id=results.user_id)
LEFT JOIN user_signups ON (user_signups.users_id=users.user_id)
GROUP BY table.field

从这里,您可以根据自己的喜好进行分组。此结构假定您的大部分数据将出现在结果表中,并将用户连接到结果表,并将 user_signups 连接到用户表。

【讨论】:

  • 你真的相信这样会更快吗?
  • 如果 user_id 字段被正确索引,它应该。
  • 没有。 最好 LEFT JOIN 将与 INNER JOIN 一样长,但在大多数情况下它会慢得多,并且会返回一个不同的值
  • 这取决于您尝试获取的结果集。如果您主要关心的是结果的总和,那么使用左连接将首先查找结果,然后将用户连接到该表。所以实际上在这种情况下它会更快。
  • 不,不会的。如果您不相信我,请尝试一下。这不是您在此处提供的查询。
【解决方案2】:

在 user_signups 表中的 (event_id, user_id, team_id) 上创建多列索引并尝试运行以下查询。 如果这不起作用,请在此处发布您的解释。

select sum(result) from results inner join(select
event_id,user_id,team_id from user_signups where event_id = 1)
user_signups on user_signups.user_id = results.user_id group by
team_id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-23
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 1970-01-01
    相关资源
    最近更新 更多