这更像是一个学术问题,因为在我的特定情况下,我可以创建一个简单的解决方法,但我想了解这背后的原因。
使用InnoDB表(MariaDB 10.0.31)和(以及其他)客户和uri列,我想为特定客户选择不同的uris。现在,该表非常大(约50M条目),因此客户和uri上有一个综合索引。
基本上我不明白为什么group by子句中列的顺序很重要。
explain select customer, uri from `tableName` group by customer,uri;
告诉我它将使用现有的group by,但是
explain select customer, uri from `tableName` group by uri,customer;
不会这样做。
有人可以解释为什么会这样吗?我一直认为group by子句是声明性的。
也许是因为它是周五,但我想不出一个案例,按列的顺序会影响结果。
答案 0 :(得分:1)
你的观察是正确的。结果会有所不同,因为复合索引声明中提到的列的“前缀”顺序用于基于成本的优化程序的决策。这种行为是由于使用了B-TREE索引
GROUP BY子句用于排序结果,因此用于
有关松散/紧密索引扫描的更多信息,请点击此处 https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html
答案 1 :(得分:0)
在索引中基本上是一个有序的表。在你的情况下,它按照ORDER BY customer, uri
的顺序排序(因为这是你的索引的定义方式)。
MySQL执行group by
首先根据group by
子句对结果进行排序,然后使用相同的值折叠行(在排序后碰巧相互跟随)。
显然,MySQL不够智能,无法识别在以其他方式排序结果时也可以执行不同的group by
子句。
更多相关信息:
答案 2 :(得分:0)
在bugs.mysql.com上写一个功能请求。
一方面,GROUP BY
被定义为(或被定义)暗示ORDER BY
具有相同顺序的相同列。
另一方面,如果您忽略该非标准功能,即使通过说ORDER BY NULL
,MySQL也无法对列进行随机播放以使用索引。
GROUP BY默认情况下隐式排序(即,在没有ASC的情况下) 或DESC指示符),但依赖于隐式GROUP BY排序 弃用。要生成给定的排序顺序,请使用显式ASC或DESC GROUP BY列的指示符或提供ORDER BY子句。组 BY排序是MySQL扩展,可能在将来的版本中发生变化; 例如,使优化器可以对分组进行排序 以任何它认为最有效的方式并避免分类 开销。
和
如果查询包含GROUP BY但您想避免开销 对结果进行排序,可以通过指定ORDER BY来抑制排序 NULL。
但请注意; 8.0说
以前,不推荐使用隐式GROUP BY排序 GROUP BY默认排序(即没有ASC或DESC时) 代号)。在MySQL 8.0中,GROUP BY默认情况下不再排序,所以 查询结果可能与以前的MySQL版本不同。生产一个 给定排序顺序,对GROUP BY使用显式ASC或DESC指示符 列或提供ORDER BY子句。