首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在非聚合列上的位置和位置。优点/缺点/无关?

在非聚合列上的位置和位置。优点/缺点/无关?
EN

Database Administration用户
提问于 2018-01-24 19:40:43
回答 2查看 8.7K关注 0票数 10

我正在重写不再需要所有数据的查询。我的问题是,我从未见过、也没有在StackExchange上发现任何专门解决这个问题的实践。

我知道HAVING语句的目的是在聚合上引入条件,就像WHERE在单个行上引入条件一样。但是,我在这段代码中看到的是,在带有聚合的查询中使用HAVING代替WHEREHAVING中的条件不是应用于聚合,而是应用于非聚合列。

例如:

代码语言:javascript
复制
SELECT id, filedate, SUM(amount)
FROM Sales
GROUP BY id, filedate
HAVING id = 123 AND filedate = '1/1/2018'

相对于:

代码语言:javascript
复制
SELECT id, filedate, SUM(amount)
FROM Sales
WHERE id = 123 AND filedate = '1/1/2018'
GROUP BY id, filedate

这种策略是否有性能方面的影响或其他优点/缺点?

我自己还没有试过运行诊断,而不是优先考虑,我必须自己去做。不过,如果没有一个明确的答案,我想我可能会的。

我关心的是优化器如何看待这个查询。它是聚合所有数据,然后根据HAVING子句限制结果集,还是实现了它可以对单个行应用有条件,因为它们专门引用非聚合列?

编辑:对于我的示例查询和我正在重写的实际SQL,这些计划是相同的,但是这些查询具有类似的复杂性,我还没有足够的知识从相同的计划中得出结论。

EN

回答 2

Database Administration用户

回答已采纳

发布于 2018-01-24 19:52:56

HAVING中的条件不是应用于聚合,而是应用于非聚合列。

这里的问题在于您如何描述HAVING子句适用于什么。HAVING子句总是应用于聚合字段,这些字段是聚合后剩下的所有列。您正在试图显示/说明HAVING子句没有应用于任何聚合函数,这正是它们通常应用的内容。但实际上,HAVING子句控制聚合函数的结果,或者,在第一个示例中,控制分组列的结果。但在这两种情况下,已经执行了聚合。

因此,在性能方面(更不用说其他尝试稍后更新此代码的人的可读性),您可以使用WHERE子句过滤到将聚合的代码,然后使用HAVING子句过滤出已经聚合的代码。而且,虽然问题中所示的简单测试的结果掩盖了这两个(或在处理查询的序列中的逻辑位置)之间的时间差异,以至于它们“似乎”在做相同的事情,但如果聚集一组行的效率不降低,但在逻辑上它们在存储/计算聚合之前就可以被删除时,我会感到非常惊讶。但是,如果您确实看到它们的执行计划对于这个简单的示例是相似的,那么我敢打赌,这仅仅是因为优化器看到在执行查询之前重写查询时使这些HAVING条件成为实际的WHERE条件会更有效。但在这种情况下,我仍然建议不要以这种方式编写查询,因为当优化器应该花费时间/ CPU周期寻找更有效的计划时,您会让优化器需要额外的时间来重写糟糕的代码。@DavidSpillett补充道(在对这个答案的评论中):“此外,您还依赖于查询规划师看到优化潜力,这在更复杂的查询中可能不是这样,或者如果您的代码最终移植到另一个数据库(甚至只是一个较旧版本的Server)。”

就其价值而言,即使是微软现有子句的文档也表示,在没有GROUP BY存在的情况下,它充当了WHERE子句。既然文档已经在GitHub上了,我最近就可以通过拉动请求#235:纠正和改进“拥有”子句更正它了。

票数 17
EN

Database Administration用户

发布于 2018-01-24 20:18:36

所罗门给出了很好的解释,但对我来说,简单的答案是记住SQL查询逻辑处理顺序,就像Itzik Ben-Gan写的这里序列总是。

从-> ->组通过->让->选择-> ORDER

所以您可以看到,如果我们可以在分组之前应用WHERE过滤器,我们可以减少按组处理的数据量,特别是当适当的索引存在时,操作会非常有效。因此,如果使用WHERE并从业务角度返回相同的结果,则WHERE总是胜利者。

票数 11
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/196158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档