暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

删除GROUP BY的隐式和显式排序

作者:Chaithra Gopalareddy 译:徐轶韬

在MySQL中,曾经 GROUP BY 也用于提供排序。如果查询指定了GROUP BY,则结果的排序就像查询中存在 ORDER BY 一样。


MySQL在这里隐式地对GROUP BY的结果进行排序(即没有对GROUP BY
指定
ASC
DESC

)。

MySQL还支持使用GROUP BY进行显式排序(即通过GROUP BY
使用显式
ASC
DESC
)。

这在8.0中已经改变,因为它不再支持GROUP BY的隐式或显式排序。在这篇博文中,我将解释为什么发生这种变化,以及为这种变化所做的前期工作。

MySQL中的GROUP BY

要对一组数据进行分组,MySQL优化器会选择不同的方法。其中之一是分组之前对数据排序。这使得连续分组变得很容易。如果有一个索引可用于获取排序的数据,那么使用它的成本会非常低廉。如果没有索引,MySQL优化器仍然可以决定在分组之前进行外部(filesort)排序。

如示例所示,在向表中添加索引之前,MySQL使用外部排序来执行GROUP BY。对于该查询,我使用SQL_BIG_RESULT强制执行该计划(因为MySQL不会为这个数据集选择此计划)。但MySQL会使用此计划在没有索引的情况下进行分组以获取已排序的数据行,并且由于存在大量组,使用临时表会变得成本过高。添加索引后,它会使用索引来执行GROUP BY。

但是在分组之前排序并不是必须的。优化器可以决定使用临时表来执行此操作。此表中的每一行都是一个分组的行,随着每一行的进入,与该表中该组对应的行将被更新。这种情况不需要排序,但由于预计MySQL中的GROUP BY将进行排序,因此会强制对分组数据进行排序。


在示例查询中,我们看到虽然使用了临时表,但MySQL仍然进行外部排序。用户必须显式指定ORDER BY NULL才能让MySQL知道GROUP BY不需要排序。因此需要一个非标准(ORDER BY NULL)语法来抵消另一个非标准扩展(GROUP BY排序)的影响。现在我们已经消除了这种混乱,它更加清晰明了。

删除GROUP BY的隐式排序

不久前,我试图修复bug71804。报告者希望MySQL在执行GROUP BY时不做这种不必要的文件排序。尝试为bug制作补丁时,让我们意识到优化这种特殊情况并不是很简单,因为GROUP BY提供隐式和显式排序。因此,我们的结论是,在进行优化之前,我们应该重构与GROUP BY相关的代码。

这样做的第一步是删除GROUP BY的隐式排序。正如在用户手册中所提到的那样,决定在一段时间后删除对它的支持。它已作为8.0中降序索引功能的一部分实现

如上例所示,不对查询执行排序。分组数据不会在最终结果中排序。如果用户需要对数据排序,则必须在查询中指定ORDER BY。

在MySQL 5.7及更低版本中,用户在手册中找到以下警告。

“ GROUP BY
默认情况下隐式排序(即,没有ASC
DESC
指示符
)。但是,不推荐依赖于隐式GROUP BY
排序(即,在没有ASC
DESC
指示符的情况下GROUP BY
)或显式
GROUP BY排序
(即,通过使用显式ASC
DESC
指示符GROUP BY
)。要生成给定的排序顺序,请使用 ORDER BY
子句。

删除GROUP BY的显式排序

当谈到删除显式排序时,遇到点小麻烦。我们无法删除它,除非MySQL支持ORDER BY进行ROLLUP。MySQL 5.7及更早版本中不允许使用ORDER BY进行ROLLUP。因此,作为替代方案,用户将使用GROUP BY ASC DESC通过ROLLUP获取排序数据(尽管排序非常严格,超级聚合行总是放在用于计算ASC的行之后,反之亦然,用于DESC) 。在删除GROUP BY的显式排序支持之前,我们必须解除此限制。

MySQL现在允许ORDER BY进行ROLLUP。我已经在https://mysqlserverteam.com/improvements-to-rollup-in-mysql/详细解释了如何使用这种改进正如在同一篇博客中所解释的,如果用户想要与MySQL 5.7 for ROLLUP完全相同的NULL排序顺序,他们应该使用GROUPING()函数以简单的方式重新编写查询。

所以简而言之,我们已经做了以下事情作为删除GROUP BY的显式排序的前期准备。

1.添加GROUPING()函数

2.删除GROUP BY的隐式排序

3.允许ORDER BY进行ROLLUP

最后,我们在MySQL 8.0.13中删除了GROUP BY的显式排序。

我们在一段时间后询问了社区意见。我们的结论是,知道MySQL提供的这个非标准扩展的用户可以接受它的消失。

结论

虽然我们在修复bug71804之前仍有一些工作要做,但我们很高兴我们完成了这项工作。请让我们知道您的想法。

感谢您使用MySQL!



最后修改时间:2019-12-24 14:17:25
文章转载自MySQL解决方案工程师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论