MySQL JOIN +子查询查询优化

时间:2012-07-22 22:38:48

标签: mysql query-optimization

我正在尝试获取100个帖子并按照他们在上周“重新混音”的次数进行排序。这是我到目前为止的查询:

SELECT COUNT(remixes.post_id) AS count, posts.title
FROM posts 
LEFT JOIN (
    SELECT * FROM remixes WHERE created_at >= 1343053513
) AS remixes ON posts.id = remixes.post_id
GROUP BY posts.id 
ORDER BY count DESC, posts.created_at DESC
LIMIT 100

这会产生正确的结果;但是,在运行DESCRIBE之后我得到了这个:

Result of the DESCRIBE syntax

以下是posts上的索引:

Posts Indexes

我的索引remixes

Remixes Indexes

以下是我的问题:

  1. 你能解释额外专栏中使用的术语真的试图告诉我的内容吗?
  2. 您是否可以提供有关如何优化此查询的提示,以便它可以更好地扩展。
  3. 提前致谢!

    更新

    Per Zane的解决方案,我已将查询更新为:

    SELECT COUNT(remixes.post_id) AS count, posts.title
    FROM posts 
    LEFT JOIN remixes ON posts.id = remixes.post_id AND remixes.created_at >= 1343053513
    GROUP BY posts.id 
    ORDER BY count DESC, posts.created_at DESC
    LIMIT 100
    

    这是最新的DESCRIBE

    LATEST DESCRIBE

    我仍然担心filesort部分。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

尽量不要将JOIN包装在子选择中,因为这将创建一个未编制索引的临时表来存储子选择的结果,然后它将连接到该未索引的表上。

相反,在加入重新混音表时,将created_at作为附加连接条件:

SELECT 
    a.title, COUNT(b.post_id) AS remixcnt
FROM 
    posts a
LEFT JOIN 
    remixes b ON a.id = b.post_id AND b.created_at >= 1343053513
GROUP BY 
    a.id, a.title
ORDER BY 
    remixcnt DESC, a.created_at DESC
LIMIT 100

答案 1 :(得分:0)

在我看来

SELECT COUNT(remixes.post_id) AS count, posts.title
FROM posts 
LEFT JOIN (
    SELECT * FROM remixes WHERE created_at >= 1343053513
) AS remixes ON posts.id = remixes.post_id
GROUP BY posts.id 
ORDER BY count DESC, posts.created_at DESC
LIMIT 100

可以改写为

SELECT COUNT(r.post_id) AS count, posts.title
FROM posts 
LEFT JOIN remixes r ON posts.id = r.post_id
WHERE r.created_at >= 1343053513
GROUP BY posts.id 
ORDER BY count DESC, posts.created_at DESC
LIMIT 100

应该为您提供更好的EXPLAIN计划并加快运行速度。