Sql HAVING和SELECT中的计算是否意味着将执行两次?
假设我有这个问题:Sql HAVING和SELECT中的计算是否意味着将执行两次?,sql,sql-server,group-by,Sql,Sql Server,Group By,假设我有这个问题: SELECT CompanyId, COUNT(*) as Total FROM Customer GROUP BY CompanyId HAVING COUNT(*) > 100 我的查询中有两次计数*。这是否意味着计数要执行两次 这是一个简单的例子,但当我有一个更复杂的计算,比如SUMWeight/COUNT*时,我担心它可能会影响性能。或者任何性能影响是否可以忽略 我使用的是MS SQL 2012,不能让总数大于100。很可能,计数*会进行两次,尽管这实际上取决
SELECT CompanyId, COUNT(*) as Total
FROM Customer
GROUP BY CompanyId
HAVING COUNT(*) > 100
我的查询中有两次计数*。这是否意味着计数要执行两次
这是一个简单的例子,但当我有一个更复杂的计算,比如SUMWeight/COUNT*时,我担心它可能会影响性能。或者任何性能影响是否可以忽略
我使用的是MS SQL 2012,不能让总数大于100。很可能,计数*会进行两次,尽管这实际上取决于查询优化器
而且,这几乎没有任何区别
聚合数据所花费的精力是移动数据,而不是聚合函数,特别是像COUNT*这样的函数。有些聚合函数的成本更高,但一般来说,数据移动比简单的聚合函数更高
您没有提到数据库,但许多人允许:
HAVING Total > 100
或者子查询/CTE的使用通常对性能没有影响。如果您对如何在封面下处理查询感兴趣,请熟悉并阅读它们。以下所有内容都是通过这些实验建立起来的 聚合不会被计算多次,但涉及它们的表达式是。考虑:
SELECT CompanyId, SUM(Weight) / COUNT(*)
FROM Customer
GROUP BY CompanyId
HAVING SUM(Weight) / COUNT(*) > 100
SUMWeight和COUNT*只计算一次,但除法将执行两次,过滤时执行一次,选择时执行一次。当然,这对性能没有可测量的影响-关键是它将必须遍历所有数据的次数降至最低
这意味着,即使您的HAVING与SELECT列表完全不同,该表仍将只扫描一次并聚合一次:
SELECT CompanyId, MAX(Weight), MIN(Weight), COUNT(*) as Total
FROM Customer
GROUP BY CompanyId
HAVING MAX(Weight) > 2 * MIN(Weight) AND AVG(Weight) > 0.5
这里有四个聚合:MAXWeight、MINWeight、AVGWeight和COUNT*。1优化器将在一次过程中计算所有这些聚合,按CompanyId对整个聚合进行分组,应用HAVING过滤器,然后选择所需的结果。2
免责声明:与所有关于优化器功能的声明一样,所有这些都可能在SQL Server的任何版本中发生更改,并且可能因跟踪标志、统计信息、索引和特定查询的具体情况而有所不同。对于SQL Server 2012和2016,至少对于索引不起作用的两个特定数据库,上述情况是正确的
AVG本身并不是一个集合;在内部,优化器将其扩展为SUM/COUNT*,并进行检查以防止被零除。所以聚合实际上是MAX,MIN,SUM和COUNT。
这是顺序计划的情况。对于并行计划,由于必须将多个并行扫描连接在一起,事情会变得稍微复杂一些,但在可能的情况下,聚合计算不会超过一次。
类似的问题啊,是的,我没有提到数据库。现在更新它。