嵌套查询性能

时间:2015-07-07 14:41:18

标签: mysql

我在下面有两个问题。第一个有嵌套选择。第二个使用group by子句。

select
  posts.*,
  (select count(*) from comments where comments.post_id = posts.id and comments.is_approved = 1) as comments_count
from
  posts 

select
  posts.*,
  count(comments.id) comments_count
from
  posts

  left join comments on
     comments.post_id = posts.id 
group by
  posts.*

根据我的理解,第一个查询更糟糕,因为它必须为帖子中的每个记录执行选择,而第二个查询不会。

这是真还是假?

3 个答案:

答案 0 :(得分:1)

与所有性能问题一样,您应该使用数据测试系统的性能。

但是,我希望第一个用正确的索引表现更好。正确的索引:

select p.*,
       (select count(*)
        from comments c
        where c.post_id = p.id and c.is_approved = 1
       ) as comments_count
from posts p

comments(post_id, is_approved)

MySQL通过执行文件排序来实现group by。此版本为所有数据保存文件排序。我的猜测是比第二种方法更快。

注意:group by posts.*是无效的语法。我认为这仅用于说明目的。

答案 1 :(得分:0)

这是我要做的标准方法(使用LEFT JOIN,SUM也让你知道哪些帖子没有评论。)

SELECT posts.*
   , SUM(IF(comments.id IS NULL, 0, 1)) AS comments_count
FROM posts
LEFT JOIN comments USING (post_id)
GROUP BY posts.post_id
;

但如果我更快地尝试, 可能会 更好。

SELECT posts.*, IFNULL(subQ.comments_count, 0) AS comments_count
FROM posts
LEFT JOIN (
   SELECT post_id, COUNT(1) AS comments_count 
   FROM comments 
   GROUP BY post_id
) As subQ
USING (post_id)
;

答案 2 :(得分:0)

经过一番研究后,我发现两个查询之间没有时间差异

<table id="example" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th width="60%">Name</th>
            <th width="40%">Position</th>
        </tr>
    </thead> 
    <tbody>
        <tr>
            <td width="60%">ABC</td>
            <td width="40%">DEF</td>
        </tr>
        <tr>
            <td width="60%">XYZ</td>
            <td width="40%">ZYX</td>
        </tr>
    </tbody>
</table>

但是我注意到在为两个查询运行解释时,第一个查询中可能有更多索引。如果选择中所需的属性发生了变化,那么我认为这是一个更好的选择。

相关问题