这并不重要,你只能得到10行。在对数据进行排序之前,MySQL必须总结每个用户的要点(“使用filesort”操作)。LIMIT最后应用。
覆盖指数ON points(user_id,point)
将是最佳性能的最佳选择。 (我真的只是猜测,没有任何EXPLAIN
输出或表定义。)
列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的前导列,并且包含point列,所以MySQL很可能通过使用索引来优化组,并避免使用“Using filesort”操作(对于GROUP BY)。
在结果集上可能会有一个“使用filesort”操作,以获得按total_points排序的行。然后从中获得前10行。
使用这10行,我们可以加入到用户表中以获取相应的行。
但是..这个结果有一个细微的差别,如果user_id
的任何值在前10位不在用户表中,那么这个查询将返回少于10行。 (我希望有一个外键定义,所以这不会发生,但我真的只是猜测没有表定义。)
EXPLAIN
将显示MySQL正在使用的访问计划。
对于这么小的表索引您参加的列上应该足以使这个查询瞬间。 – piotrm