2008-11-30 73 views
32
SELECT NR_DZIALU, COUNT (NR_DZIALU) AS LICZ_PRAC_DZIALU 
    FROM PRACOWNICY 
    GROUP BY NR_DZIALU 
    HAVING NR_DZIALU = 30 

哪個SQL語句更快? (HAVING與WHERE ...)

SELECT NR_DZIALU, COUNT (NR_DZIALU) AS LICZ_PRAC_DZIALU 
    FROM PRACOWNICY 
    WHERE NR_DZIALU = 30 
    GROUP BY NR_DZIALU 

回答

56

理論(理論上我的意思是SQL Standard)表示WHERE在返回行之前限制結果集,並且在引入所有行後限制結果集。所以WHERE更快。在這方面,在符合SQL標準的DBMS上,只能使用HAVING,而不能將條件放在WHERE(如某些RDBMS中的計算列)。

您可以只看到兩者的執行計劃並檢查自己, (用您的數據測量您在特定環境中的具體查詢)。

+0

在Sybase DB下它有150行的執行時間:) – 2008-11-30 08:56:39

+0

我說的執行計劃,在這裏你可以看到數據庫將執行什麼步驟來獲取你的數據。 150行太少,不足以注意到執行時間的差異,但如果計劃不同,那麼對於具有更多行數的表而言,這一點很重要。 「運行查詢前設置showplan on」... – 2008-11-30 09:19:59

2

我期望的WHERE子句會更快,但它可能他們會優化完全相同的。

8

它可能取決於引擎。例如,MySQL幾乎將HAVING應用於鏈中,意味着幾乎沒有優化空間。從manual

HAVING子句幾乎最後應用,只是在項目被髮送到客戶端,沒有優化。 (LIMIT在HAVING之後應用)

我相信這種行爲在大多數SQL數據庫引擎中是相同的,但我無法保證它。

5

這兩個查詢是等價的,你的DBMS查詢優化器應該認識到這一點併產生相同的查詢計劃。它可能不是,但情況很簡單,所以我期望任何現代系統 - 甚至Sybase - 都能處理它。

HAVING子句應該用於在組函數上應用條件,否則它們可以被移植到WHERE條件中。例如。如果你想限制查詢到具有COUNT(DZIALU)> 10的組,那麼你需要將條件放入HAVING中,因爲它作用於組而不是單獨的行。

2

說他們會優化並沒有真正控制和告訴計算機該做什麼。我同意使用「有」不是where子句的替代。通過使用諸如sum()之類的東西,並且您希望限制結果集僅顯示sum()>大於100本身的組,將它應用於某個組的特殊用法。對小組有作用,在行上工作。他們是蘋果和桔子。所以真的,他們不應該被比較,因爲它們是兩種截然不同的動物。

0

這兩個語句的性能都與SQL Server足夠聰明,可以將相同的語句解析爲類似的計劃。

因此,如果您在查詢中使用WHERE或HAVING,則無關緊要。

但是,理想情況下,您應該在語法上使用WHERE子句。