2016-07-04 60 views
0

假設我的模型包含2個表格:個人和地址。一個人可以有O個,一個或多個地址。我試圖執行一個查詢,列出所有人,幷包括他們分別擁有的地址數量。這裏是2個查詢,我要做到這一點:加入vs子查詢來計算嵌套對象

SELECT 
    persons.*, 
    count(addresses.id) AS number_of_addresses 
FROM `persons` 
    LEFT JOIN addresses ON persons.id = addresses.person_id 
GROUP BY persons.id 

SELECT 
    persons.*, 
    (SELECT COUNT(*) 
    FROM addresses 
    WHERE addresses.person_id = persons.id) AS number_of_addresses 
FROM `persons` 

,我想知道,如果一個比其他在性能方面更好。

+0

這是什麼'cube_models'表,爲什麼它只出現在第二個查詢中?第二個查詢使用相關的子查詢,它通常傾向於比使用聯接的類似查詢慢。 –

+1

我相信第一個會更快,但它們非常相似。只需在兩者上運行執行計劃並查看差異。我懷疑有沒有更好的辦法。 – sagi

+0

我修復了cube_models,壞的複製/粘貼 – TrexXx

回答

0

確定性能特徵的方法是實際運行查詢並查看哪個更好。

如果你沒有索引,那麼第一個可能會更好。如果你有addresses(person_id)的索引,那麼第二個可能會更好。

原因有點複雜。基本原因是group by(在MySQL中)使用排序。而且,排序是複雜度爲O(n * log(n))。所以,進行排序的時間比數據增長得快(速度並不快,但有點快)。結果是,每個人的一堆聚合比一個人聚合的速度快於所有數據。

這是概念。事實上,MySQL將使用相關子查詢的索引,所以它通常比不使用索引的整體group by更快。

0

我認爲第一個查詢是最優的,更多的優化可以通過改變表結構來提供。例如,將地址表中的主鍵定義爲person_id和address_id字段(順序很重要),以加快加入速度。

mysql表存儲結構是索引組織表(聚集索引),所以主鍵索引在聯接操作中特別快於正常索引。

+0

'persons.id','addresses.id'和'addresses.person_id'都有索引 – TrexXx

+0

@TrexXx,mysql表存儲結構被索引組織表(clustered),因此主關鍵指標特別在連接操作中比正常指標快很多。 –