2008-11-30 116 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子句。