【问题标题】:Azure SQL Database Group By not sortingAzure SQL 数据库组按不排序
【发布时间】:2014-02-01 14:09:03
【问题描述】:

几年来,我一直在 Windows Azure SQL 数据库(以前的 SQL Azure)中使用以下查询,并且它始终按字段分组排序。

SELECT CAST(OccurredDate AS DATE) as OccurredDate, COUNT(*) AS [Count], COUNT(DISTINCT CreatedByUserId) AS NumOfUsers 
FROM [TableName] 
GROUP BY CAST(OccurredDate AS DATE)

我今天突然运行了这个查询,它不再对结果进行排序。

我认为 GROUP BY 总是对其正在处理的列进行排序。

非常感谢任何见解。

【问题讨论】:

标签: sql-server sorting azure group-by azure-sql-database


【解决方案1】:

不,GROUP BY 不一定排序(虽然这在 SQL Server 2000 中相对可靠,但在技术上仍不能保证;2005 年对优化器的更改改变了这种行为,因此绝对不能依赖它)。如果您之前收到过特定订单,那纯属巧合。

如果您想要一个可预测的订单,添加一个 ORDER BY。期间。

在这种情况下,由于 ORDER BY 是最后处理的,因此您不必重复表达式,只需使用 SELECT 列表中的别名即可:

ORDER BY OccurredDate;

【讨论】:

    【解决方案2】:

    我想详细说明 Aaron 的回应。这不仅仅是一个“优化器”问题,而是一个算法问题。

    大多数人一想到聚合,就会想到以下方法:

    1. 按要聚合的字段对数据进行排序(或遍历键的索引)
    2. 浏览数据并确定小组的起点
    3. 聚合具有相同键值的所有行的值(由于排序,它们彼此相邻)
    4. 继续下一组

    当你运行这个算法时,一个结果是结果是有序的。而这也是一些数据库(如Access和MySQL)提供的唯一算法。

    第一点是,即使是这种算法也不能保证在并行(多线程/多服务器)环境中按顺序返回数据。例如,环境中的第一步可能是将所有以“A”开头的字符串放在一个处理器(或线程)上,“B”放在另一个处理器上,等等。然后每个处理器在本地进行聚合。

    重要的一点是处理器不一定同时完成。例如,“X”可能早于“S”结束。而且,这意味着“X”的结果首先返回。瞧,结果不正常。

    第二点比较重要。 SQL Server(和其他智能数据库)有其他算法来进行聚合。上述算法实际上是一种混合算法——首先将值“散列”,这意味着“相似”值在每个处理器上汇集在一起​​,然后对其余的值进行排序以进行聚合。 “散列”保证具有相同值的所有键都在同一个处理器上。

    这也可以用于最终算法。当您使用基于哈希的算法时,结果肯定不是按排序顺序排列的,因为在处理过程中不会发生排序。令人高兴的是,SQL Server 支持聚合和连接的基于散列的算法,因此您不会期望对结果进行排序。

    【讨论】:

    • 虽然如此,但我认为重要的是要注意,在分组时使用的 算法 SQL Server 2000 与现在并没有什么不同。碰巧他们有一个步骤,他们以与分组相同的顺序排列结果,这是一个已被丢弃的步骤,因为它被认为是不必要的(我认为阻止了一些出现的优化)。
    • 感谢 Gordon 提供的详细信息。这是有道理的,正在处理的数据量可能导致 Azure SQL DB 中使用了不同的算法。我这样说是因为这个查询已经使用了 2 年多了,并且总是返回有序的结果。
    • @user3260560 它可以返回 10 年内以一种方式排序的结果。这并不意味着它是设计的,更不用说保证了;它可以根据至少十几个不同的影响因素在瞬间发生变化。你是巧合的受害者,仅此而已。 Azure 优化器不会生成与其他版本的 SQL Server 不同的查询计划,它当然不会以任何不同的方式处理 GROUP BY。您需要在这里信任我们,当您迁移到 Azure 时,这并没有“停止工作”。它只是“发生”了之前的工作。
    • 我猜测该顺序可能与 Azure SQL 对聚集索引的坚持有关?但我很可能会错。
    猜你喜欢
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多