gpt4 book ai didi

sql - HAVING 和 SELECT 中的计算是否意味着它将执行两次?

转载 作者:行者123 更新时间:2023-12-03 02:53:54 24 4
gpt4 key购买 nike

假设我有这个查询:

SELECT CompanyId, COUNT(*) as Total
FROM Customer
GROUP BY CompanyId
HAVING COUNT(*) > 100

我的查询中有两次 COUNT(*) 。这是否意味着 COUNT 执行了两次?

这是一个简单的示例,但是当我进行更复杂的计算(例如 SUM(Weight)/COUNT(*))时,我担心它可能会影响性能。或者任何性能影响都可以忽略不计?

我使用的是 MS SQL 2012,无法执行 HAVING Total > 100

最佳答案

如果您对查询的幕后处理方式非常感兴趣,请熟悉 execution plans以及如何阅读它们。以下所有内容都是使用这些实验建立的。

聚合不会被计算多次,但涉及它们的表达式却会被计算多次。考虑:

SELECT CompanyId, SUM(Weight) / COUNT(*)
FROM Customer
GROUP BY CompanyId
HAVING SUM(Weight) / COUNT(*) > 100

SUM(Weight)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

这里有四个聚合:MAX(Weight)MIN(Weight)AVG(Weight)COUNT( *).1 优化器将一次性计算所有这些,按 CompanyId 对整体进行分组,应用 HAVING 过滤器然后选择所需的结果。2

免责声明:与有关优化器功能的所有声明一样,所有这些都可能在 SQL Server 的任何版本中发生更改,并且可能会因跟踪标志、统计信息、索引和特定查询的具体情况而异。上述情况对于 SQL Server 2012 和 2016 来说是正确的,至少对于两个特定的数据库来说是正确的,其中索引不起作用。

<小时/>
  1. AVG 实际上本身并不是一个聚合;在内部,优化器将其扩展为 SUM/COUNT(*),并进行检查以防止被零除。因此,聚合实际上是 MAXMINSUMCOUNT
  2. 这是顺序计划的情况。对于并行计划,由于必须将多个并行扫描连接在一起,事情会变得更加复杂,但聚合不会计算多次(如果可能)。

关于sql - HAVING 和 SELECT 中的计算是否意味着它将执行两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45878781/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com