我有两个表 - 用户(id,name)和user_comments(user_id,comment_content)。 问题是获得有限数量(实际上是10个)的用户(实际名称),按注释计数排序。 user_comments表可以包含users表不包含的一些user_ids(无效ID),必须忽略这些行。
起初我写了这个简单的连接查询:
SELECT users.name, COUNT(*) AS comment_count
FROM user_comments
JOIN users ON users.id = user_comments.user_id
GROUP BY id
ORDER BY comment_count DESC
LIMIT 0, 10
此查询工作正常 - 对于18.000个用户和21.000条评论,为0.2秒。
然后我决定优化查询(不是结构,我不能更改/添加索引),我写了这个查询:
SELECT users.name, top_active_users.comment_count
FROM ( SELECT user_id, COUNT(user_id) AS comment_count
FROM user_comments
GROUP BY user_id
ORDER BY comment_count DESC ) AS top_active_users
JOIN users ON users.id = top_active_users.user_id
LIMIT 0, 10
这个工作速度更快(约5次) - 18.000个用户的0.04秒和21.000个评论。 我认为第二个工作得更快,因为它没有将top_active_users子查询中的每一行与用户表的行连接起来。由于LIMIT 0,10它只从具有有效user_id的子查询结果中加入10行。第一个查询必须连接所有行,然后按顺序排列,然后只需要10行。
现在的问题是,我认为是对的,如果是的话,我如何调试查询以查看第二个查询的优势。
我认为mysql探查器(EXPLAIN,DESCRIBE)不能使用LIMIT。
谢谢。
答案 0 :(得分:2)
基本上你的假设基本上是正确的。
在您的第二个更快的查询中,您只处理一个表中的一列。它可能已编入索引,因此GROUP BY
操作不需要任何预先分类。然后使用该结果集从users
表中提取信息。而且,由于LIMIT
,您只需要提取十行的数据。
AFAIK,EXPLAIN
与LIMIT
一起正常使用。 LIMIT
ed查询是一个重要的优化案例。