mysql - GROUP BY 子句中列的顺序确实会影响索引的使用

标签 mysql sql mariadb

这更像是一个学术问题,因为在我的特定情况下我可以创建一个简单的解决方法,但我还是想了解这背后的原因。

使用带有(以及其他)列 customer 和 uri 的 InnoDB 表 (MariaDB 10.0.31),我想为特定客户选择不同的 uri。现在,该表非常大(大约 5000 万个条目),因此在 customer 和 uri 上有一个复合索引。

基本上我不明白的是为什么 group by 子句中列的顺序很重要。

explain select customer, uri from `tableName` group by customer,uri;

告诉我它将使用现有索引进行分组,但是

explain select customer, uri from `tableName` group by uri,customer;

不会这样做。

有人能解释一下为什么会这样吗?我一直认为 group by 子句是声明性的。

可能因为今天是星期五,但我想不出按列分组的顺序会影响结果的情况。

最佳答案

您的观察是正确的。结果会有所不同,因为复合索引声明中提到的列的“前缀” 顺序用于基于成本的优化器的决策制定。此行为是由于使用了 B-TREE 索引

GROUP BY 子句用于对结果进行排序,因此如果

  • 使用正确的索引顺序或
  • 分组依据只使用最左边的列
  • 最左边的列在 WHERE 子句中使用,在 GROUP BY 子句中以正确的顺序排列,将使用索引。

有关此主题和松/紧索引扫描的更多信息,请参见此处 https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html

关于mysql - GROUP BY 子句中列的顺序确实会影响索引的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46975277/

相关文章:

mariadb - 无法创建 MariaDB Galera 集群

mysql - 非常小的 MySQL 表会忽略索引吗?

javascript - 在 Node.js 程序中运行纯 JavaScript 查询是否存在安全问题?

mysql - 无法添加外键mysql错误1215

mysql - 为什么 Laravel 时间戳字段可以为空?

mysql - MySQL 中按 2 列分组并对其他 2 列求和

MySQL/MariaDB 添加列文档

mysql - 如何在我的 CodeIgniter 模型中使用 ON DUPLICATE KEY UPDATE?

mysql - 根据描述对列进行排序

sql - MySQL MATCH...AGAINST 有时会找到答案,有时不会