在 group by 子句之后是否需要 order by?

9 sql-server

假设我有一个简单的查询

SELECT col1, col2, COUNT(col3)  
FROM tbl_name    
WHERE condition    
GROUP BY col1, col2    
ORDER BY col1 ;
Run Code Online (Sandbox Code Playgroud)

我的理解是 group by 子句似乎已经具有排序功能。如果 col1 的相邻行碰巧具有相同的值,则 DB 引擎将对 col1 进行排序,然后对 col2 进行排序。至少这是我使用 sql server 的经验。

如果是这样的话,这里的 order by 子句真的没有必要吗?

Mar*_*ith 16

我的理解是 group by 子句似乎已经具有排序功能。

SQL Server 可以使用两种基本方法。流聚合要求数据按关键字分组进行排序。这可以由索引提供,也可以需要显式排序。流聚合是顺序保留的,因为该运算符输出的行与输入的顺序相同。然而,这并不意味着对整个查询的最终输出有任何保证。只有在添加ORDER BY.

对于 a GROUP BY col1, col2,在这种情况下,输入流可以由流聚合排序col1, col2col2, col1可接受。添加索引可能会改变优化器关于使用哪个索引的决定。

另一种基本方法是散列聚合。其中分组键被散列。这根本不是顺序保留,并且可能会以看似随机的顺序输出行。

此外,对于并行计划,可能存在混合方法,例如,每个线程都可以有一个本地流聚合,其中包含线程结果,然后在全局级别使用散列聚合进行聚合。

添加ORDER BY意味着 SQL Server 将确保按所需顺序传送行。如果您当前正在观察的输出顺序为 ,col1, col2那么您可能会获得由这两列排序的流聚合。添加显式 order by 不会更改执行计划以添加任何其他排序,因为 SQL Server 将识别此聚合的输出已按所需顺序排列。


Aar*_*and 14

是的,这ORDER BY是必要的,除非您实际上并不关心订单。仅仅因为您观察到某种类型的排序并不能保证它。基本上,如果您省略该ORDER BY子句,您就是在告诉 SQL Server 您不关心顺序,并且可以按照它认为最有效的任何顺序自由返回数据。它会;请参阅此处的 #3:

如果你想要那个顺序,实际输入ORDER BY你想要的有什么害处?这记录了查询,确保您始终获得所需的结果,而且我不确定将其排除在外会为您带来什么。13 个保存的按键?少一行代码?为什么人们想要不遗余力地使他们的代码模棱两可且不可靠?