与您仅获得 10 行相比,这并不重要。MySQL 必须为每个用户总结点,然后才能对它们进行排序(“使用文件排序”操作。)最后应用 LIMIT。
覆盖指数ON points(user_id,point)
将是获得最佳性能的最佳选择。(我真的只是在猜测,没有任何EXPLAIN
输出或表定义。)
中的id
列users
可能是主键,或者至少是唯一索引。所以很可能你已经有一个id
作为前导列的索引,或者如果它是 InnoDB,则为主键集群索引。)
我很想测试这样的查询:
SELECT u.*
, s.total_points
FROM ( SELECT p.user_id
, SUM(p.point) AS total_points
FROM points p
WHERE p.user_id > 0
GROUP BY p.user_id
ORDER BY total_points DESC
LIMIT 10
) s
JOIN user u
ON u.id = s.user_id
ORDER BY s.total_points DESC
这确实有创建派生表的开销,但是在点上有一个合适的索引,有一个 user_id 的前导列,并且包括点列,MySQL 很可能可以通过使用索引来优化组,并避免一个“使用文件排序”操作(用于 GROUP BY)。
该结果集上可能会有一个“使用文件排序”操作,以获取按总点数排序的行。然后从中获取前 10 行。
有了这 10 行,我们可以连接到用户表以获取相应的行。
但是.. 这个结果有一点不同,如果其中任何一个值user_id
在前 10 名中而不在用户表中,那么这个查询将返回少于 10 行。(我希望定义一个外键,所以这不会发生,但我真的只是在猜测没有表定义。)
将EXPLAIN
显示 MySQL 正在使用的访问计划。