2015-06-14 84 views
2

的是这两个MySQL之间的区别查询子查询和联接的子查询有什么区别?

select t.id, 
(select count(c.id) from comment c where c.topic_id = t.id) as comments_count 
from topic; 

select t.id,comments.count from topic 
left join 
(
    select count(c.id) count,c.topic_id from comment c group by topic_id 
) as comments on t.id = comments.topic_id 

我知道那里有没有太多的信息。只是想知道什么时候使用子查询并加入了子查询以及它们之间的区别。

感谢

+2

你的第二个例子是一个派生表的连接。好处是派生表是一次生成,基于集合。第一个相关的子查询可能会在“topic”表的每一行中执行一次 – StuartLC

+0

所以,你的意思是子查询可以检索单个记录吗?和第二个撤回清单? – reverbnation

+0

@reverbnation如果你想提出一个StuartLC的问题,你应该用@ @ – 2015-06-14 15:38:16

回答

0

这是一个很好的问题,但我也想补充第三个选项(这样做的更标准的方式):

select t.id, count(c.topic_id) as count 
from topic left join 
    comment c 
    on t.id = c.topic_id 
group by t.id; 

第一种方式往往是最有效的在MySQL 。 MySQL可以利用comment(topic_id)上的索引来生成计数。在其他数据库中也可能是这样,但在实践中不使用group by的索引的MySQL中尤其明显。

第二个查询执行聚合,然后进行连接。子查询已实现,增加了额外开销,然后join无法使用comment上的索引。它可能使用topic上的索引,但left join可能会使该选项不太可能。 (您需要检查环境中的执行计划。)

第三个选项等同于许多数据库中的第一个,但不在MySQL中。它会加入comment(利用comment(topic_id)上的索引,如果有的话)。但是,它会导致最终聚合的文件排序开销。

不得不承认,在MySQL的性能方面,第一选择往往是最好的,特别是如果有正确的索引可用的话。没有索引,三者中的任何一个都可能是最好的选择。例如,如果没有索引,第二个是最好的,如果comments是空的或有很少的话题。

+0

来称呼他。你最后一段有点含糊。哪一个更适合没有索引?哪一个索引? – 2015-06-14 15:35:11