更新时间:2022-10-26 GMT+08:00

distinct与group by优化

场景描述

使用distinct或group by的语句执行比较慢。

原因分析

大部分情况下,distinct是可以转化成等价的group by语句。在MySQL中,distinct关键字的主要作用就是去重过滤。

distinct进行去重的原理是先进行分组操作,然后从每组数据中取一条返回给客户端,分组时有两种场景:

  • distinct的字段全部包含于同一索引:该场景下MySQL直接使用索引对数据进行分组,然后从每组数据中取一条数据返回。
  • distinct字段未全部包含于索引:该场景下索引不能满足去重分组需要,会用到临时表(首先将满足条件的数据写入临时表中,然后在临时表中对数据进行分组,返回合适的数据)。因为使用临时表会带来额外的开销,所以一般情况下性能会较差。

综上,在使用distinct或group by的时候,尽量在合理的情况下设置可以包含所有依赖字段的索引,优化示例:

  • 没有合适索引,导致需要用到临时表。

  • 有合适的索引,不会使用临时表,直接走索引。

解决方案

在使用distinct或group by的时候,尽量在合理的情况下,创建可以包含所有依赖字段的索引。