【问题标题】:MySQL query optimization and debuggingMySQL查询优化和调试
【发布时间】:2014-11-24 00:26:04
【问题描述】:

我有两个表 - users(id, name) 和 user_cmets(user_id, comment_content)。 问题是获得有限数量(实际上是 10 个)的用户(实际上是名称),按 cmets 计数排序。 user_cmets表可以包含一些users表不包含的user_ids(invalid ids),这些行必须忽略。

一开始我写了这个简单的连接查询:

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 个 cmets 需要 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 个用户和 21.000 个 cmets 为 0.04 秒。 我认为第二个工作得更快,因为它不会将 top_active_users 子查询中的每一行与 users 表的行连接起来。由于 LIMIT 0, 10 它只连接子查询结果中具有有效 user_ids 的 10 行。第一个查询必须连接所有行,然后排序,然后只取 10 行。

现在的问题是,我认为对吗?如果是,我该如何调试查询以查看第二个查询的优势。

mysql profiler(EXPLAIN, DESCRIBE) 不适用于 LIMIT 我猜。

谢谢。

【问题讨论】:

    标签: mysql sql join optimization query-optimization


    【解决方案1】:

    您对为什么这更快的假设基本上是正确的。

    在第二个更快的查询中,您只处理一张表中的一列。它可能已编入索引,因此 GROUP BY 操作不需要任何预排序。然后使用该结果集从users 表中提取信息。而且,由于LIMIT,您只需要提取十行的数据。

    AFAIK,EXPLAINLIMIT 一起正常工作。 LIMITed 查询是一个重要的优化案例。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2020-03-28
    • 1970-01-01
    • 2011-01-22
    • 2011-07-07
    • 2018-12-21
    相关资源
    最近更新 更多