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

标签 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

最佳答案

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

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

... ON users (country, id)

... ON games (user_id) 

解释

您需要一个以 country 作为前导列的索引,这样 MySQL 就可以使用该索引来执行 GROUP BY 操作,而不是使用昂贵的“Using filesort”操作。

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

games 表上的索引以 user_id 开头,这意味着 MySQL 可以使用该索引来获取计数。

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

关于MySQL获取与其他表匹配的前10项以对它们进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22492820/

相关文章:

mysql:为什么左连接不使用索引?

sql - 使用内连接更新记录

MySQL 计算每个成员子类型每小时的签到次数

mysql - 如何为 InnoDB 引擎数据库重新播种 "Auto increment"列?

mysql - Nodejs Mysql Select Count 嵌套循环插入查询

css - WP 移动样式 css 与 wp_head 功能

python - 在两个数组中查找共同值的索引

css - 浏览器何时会下载样式表中定义的背景图像?

mysql - INNER JOIN 中的子查询 (MySQL)

php - 如何显示特定div中的mysql表?