2012-10-17 184 views
8

我可以以兩種方式使用聚合函數編寫一個查詢:HAVING子句VS子查詢

select team, count(min) as min_count 
from table 
group by team 
having count(min) > 500 

select * 
from (
    select team, count(min) as min_count 
    from table 
    group by team 
) as A 
where A.min_count > 500 

是否有任何一種方法的任何性能優勢,或者是他們在功能上同樣的事情?

+1

最重要的是:它們在語義上是否相同? – usr

+0

你測試了他們還是查看解釋計劃? – Taryn

+0

你可以顯示查詢執行計劃嗎? –

回答

5

這兩個版本在功能上是相同的。那麼,第二個是語法不正確,但我相信你的意思是:(你需要在計算中的別名和幾個主要的數據庫需要在一個FROM子句的子查詢的別名)

select * 
from (
    select team, count(min) as count 
    from table 
    group by team 
) t 
where count > 500 

被在功能上等同於並不是意味着它們必然以相同的方式優化。通常有多種方式來編寫功能相同的查詢。但是,特定的數據庫引擎/優化器可以選擇(並經常選擇)不同的優化路徑。

在這種情況下,查詢非常簡單,以至於很難考慮多個優化路徑。對於這兩個版本,引擎基本上必須彙總查詢,然後測試過濾​​器的第二列。我個人無法看到這個主題的很多變化。如果合適的話,任何體面的SQL引擎都應該使用索引,無論是這兩種情況還是兩者都不。因此,對於這個具體問題的爭論是,在任何合理的數據庫中,這些應該導致相同的執行計劃(即,在使用索引,並行的用戶以及聚合算法的選擇中)。然而,功能上的等同並不意味着給定的數據庫引擎將產生相同的exeuction計劃。所以,一般的答案是「不」。