MySQL获得与其他表匹配的前10个项目以对它们进行分组

时间:2014-03-18 22:56:42

标签: mysql performance inner-join

也许标题没有得到很好的解释。 我有这个:

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 个答案:

答案 0 :(得分:0)

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

对于此查询,看起来您需要这些索引:

... ON users (country, id)

... ON games (user_id) 

<强>说明

您希望使用country作为前导列的索引,因此MySQL可以使用索引来执行GROUP BY操作,而不是使用昂贵的“使用filesort”操作。

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

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

我们希望MySQL在EXPLAIN的Extra列中显示“Using index”。