我在下面有两个问题。第一个有嵌套选择。第二个使用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.*
根据我的理解,第一个查询更糟糕,因为它必须为帖子中的每个记录执行选择,而第二个查询不会。
这是真还是假?
答案 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>
但是我注意到在为两个查询运行解释时,第一个查询中可能有更多索引。如果选择中所需的属性发生了变化,那么我认为这是一个更好的选择。