2015-06-14 83 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