区别于PARTITION BY与GROUPBY



我在一个正在检查的应用程序中发现了一些SQL查询,如下所示:

SELECT DISTINCT
Company, Warehouse, Item,
SUM(quantity) OVER (PARTITION BY Company, Warehouse, Item) AS stock

我确信这会得到与相同的结果

SELECT
Company, Warehouse, Item,
SUM(quantity) AS stock
GROUP BY Company, Warehouse, Item

使用第一种方法比使用第二种方法有什么好处(性能、可读性、编写查询的额外灵活性、可维护性等)吗?

性能:

获胜者:GROUP BY

在一个没有索引列的大表上进行的一些非常基本的测试表明,至少在我的情况下,这两个查询生成了完全不同的查询计划。CCD_ 2的速度明显较慢。

GROUP BY查询计划只包括一个表扫描和聚合操作,而PARTITION BY计划有两个嵌套的循环自联接。PARTITION BY第二次运行耗时约2800ms,GROUP BY仅耗时500ms。

可读性/可维护性:

获胜者:GROUP BY

根据评论人士的意见,PARTITION BY对大多数开发人员来说可读性较差,因此在未来可能也更难维护。

灵活性

获胜者:PARTITION BY

PARTITION BY在选择分组列时提供了更大的灵活性。使用GROUP BY,所有聚合列只能有一组分组列。使用DISTINCT + PARTITION BY,您可以在每个分区中拥有不同的列。此外,在某些DBMS上,您可以从OVER子句中的更多聚合/分析函数中进行选择。

不需要使用sum()作为over partition by的分析函数。我认为他们之间在任何意义上都没有太大的区别。在oracle中,分析函数比聚合函数多得多。我认为ms-sql也是如此。例如,lag()lead()rank()dense rank()等仅用PARTITION BY0实现要困难得多。当然,这个论点并不是为了捍卫第一个版本。。。

也许结果集中以前有更多的计算字段,这些字段无法通过group-by-实现。

尽管当您查看列时,两个查询似乎计算的内容相同,但它们实际上产生了完全不同的行集。

使用分析函数的第一个将为每个输入行输出恰好一行。也就是说,对于每个库存信息,它将返回一行,其中包含关联公司/仓库/物料的总数量。(顺便说一句,计算平均值对我来说更有意义,但谁知道呢…)

第二个将只为每个公司/仓库/项目组合返回一行。

是的,在这个例子中,第一个查询似乎有点无用。。。除非你想计算一些库存水平的统计数据,比如按公司/仓库/物品计算的当前库存占总数量的比率(只是一个例子,不知道它是否有任何商业意义!)

分析函数是SQL中非常强大的机制,在某种意义上比分组更强大。但要小心使用。。。一个简单的经验法则可能是:如果你可以通过使用一个组来计算它,那么,不要使用分析函数;)

最新更新