使用中间表优化MySQL Join和Group By

时间:2016-01-09 00:17:22

标签: mysql query-optimization

简化,但我有三张桌子:

  • 用户(user_id,team_id)
  • results(user_id,result)
  • 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

很快。 “Explain”的结果是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秒)。 “Explain”的结果包含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

还有其他建议吗?

2 个答案:

答案 0 :(得分:0)

通过对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加入users表。

答案 1 :(得分:0)

在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