mysql:简单的子查询非常慢,因为有3000万行

时间:2014-03-19 02:51:30

标签: mysql sql

我试图获取每个帖子和评论的列表。

SELECT
    theposts.id, 
    theposts.name,
    (SELECT COUNT(*) FROM thecomments WHERE thecomments.post_id = theposts.id) AS comments
FROM theposts

问题是:我有20k帖子和3000万条评论。查询非常慢。

如果我使用LIMIT 5,它可以在大约40秒内正常工作。但我需要获得20k帖子的完整列表。

有关如何加速或调试此查询的任何提示?

服务器正在我的Macbook 8gb ram中运行。

3 个答案:

答案 0 :(得分:3)

我能想到的最好的方法是创建一个索引。您需要thecomments(post_id)上的索引:

create index thecomments_postid on thecomments(post_id);

这应该将查询计划更改为仅进行索引扫描并快速完成。

我也认为这比使用group by更快,这是另一种可能性:

SELECT theposts.id, theposts.name, COUNT(*) as comment
FROM theposts join
     thecomments
     on thecomments.post_id = theposts.id
GROUP BY theposts.id;

答案 1 :(得分:1)

首先要检查您是否有适当的索引。这通常是最常见的问题。

另一个问题是,您可能正在运行20,000个子查询,具体取决于您的查询分析引擎的智能程度。

只需对行进行分组,您就可以在一个查询中获得相同的结果,例如with(取决于您的架构):

SELECT
    theposts.id           is id, 
    theposts.name         as name,
    count(thecomments.id) as comments
FROM
    theposts, thecomments
WHERE
    thecomments.post_id = theposts.id
GROUP BY thepost.id, theposts.name

(这是隐式样式连接语法,您也可以使用显式join)。

答案 2 :(得分:1)

尝试使用join,你不需要子查询。

SELECT
   theposts.id, 
   theposts.name,
   COUNT(*) comments
FROM thecomments 
INNER JOIN theposts ON thecomments.post_id = theposts.id
GROUP BY theposts.id