使用中间表优化 MySQL Join 和 Group By
Posted
技术标签:
【中文标题】使用中间表优化 MySQL Join 和 Group By【英文标题】:Optimizing MySQL Join and Group By with intermediate table 【发布时间】: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
。
【参考方案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
【讨论】:
以上是关于使用中间表优化 MySQL Join 和 Group By的主要内容,如果未能解决你的问题,请参考以下文章