2014-03-18 142 views
1

也许标题没有很好地解释。 我有这样的:MySQL获得与其他表匹配的前10项匹配

users (id, name) 
----------------------- 
| 1 | User 1 | US | 
| 2 | User 2 | US | 
| 3 | User 3 | FR | 
| 4 | User 4 | IT | 
| 5 | User 5 | US | 
| ... | ...... | .. | 
------------------------ 

games (game_id, user_id) 
--------------- 
| 1 | 2 | 
| 2 | 4 | 
| 3 | 1 | 
| 4 | 6 | 
| ...| ... | 
--------------- 

我需要的是获得最高的国家打比赛,所以答案,如:

1 US 145 games 
2 FR 25 games 
3 IT 12 games 
... 
up to 10 results 

我的解决办法是这样的,但它的速度太慢(有百万条记录)

select 
    distinct(user.country), 
    count(*) as counter 
from games 
    inner join user on games.user_id = user.id 
group by user.country 
order by counter DESC 
limit 10 
+1

'DISTINCT'是关键字,而不是函数。 'user.country'周围的parens是不必要的。他们不影响声明。实际上,在这个查询中,'DISTINCT'关键字是不必要的,因为有一个'GROUP BY user.country'子句。 – spencer7593

+0

我建议您使用'EXPLAIN'来验证查询是否使用JOIN操作的合适索引。你可以用'EXPLAIN SELECT ...'的输出来更新你的问题。快速回答为MySQL提供了适当的索引,但在不知道MySQL正在做什么的情况下给出答案是没有意义的。 – spencer7593

+0

每个用户有多少游戏?你有什么指标在桌子上? –

回答

0

为了获得最佳性能,MySQL需要有合适的索引。

对于此查询,看起来像你想要这些指标:

... ON users (country, id) 

... ON games (user_id) 

说明

你想country作为领先列的索引,因此MySQL可以使用索引来执行GROUP BY操作,而不是使用昂贵的“使用filesort”操作。

让用户id列作为该索引中的辅助列可用意味着它将成为覆盖索引,MySQL不需要访问基础表中的页面。

前导列为user_id的游戏桌上的索引意味着MySQL可以使用索引来获取计数。

我们预计MySQL会在EXPLAIN的Extra列中显示“使用索引”。