You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中替代distinct on实现高效查询的方法

问题

我的查询运行耗时过长,通过执行计划分析发现“unique”节点占用大量计算时间。目前我用窗口函数max(grade) over (partition by class)计算每个班级的最高成绩,再通过distinct on (class)来保留每个班级的结果。

示例数据:

班级学生成绩
1A0
1B10
1C11
1D7
2E20
2F18
2G19

需求是获取每个班级的最高成绩:

班级最高成绩
111
220

当前使用的SQL语句:

select distinct on (class)
       class, max_grade 
from (select max(grade) over (partition by class) as max_grade,
             student,
             class) t

请问是否有比distinct on更优的方式实现该结果?

优化方案

直接用分组聚合是更高效的实现方式,完全不需要窗口函数和distinct on,能彻底避免unique节点带来的额外开销:

select class, max(grade) as 最高成绩
from your_table_name
group by class

方案优势

  • 分组聚合是这类“按组求极值”需求的原生解决方案,PostgreSQL会直接对class分组后计算最大值,执行计划更简洁,省去了先为每一行生成窗口函数结果再去重的步骤。
  • 对比原方案,减少了子查询的内存占用,也规避了distinct on触发的排序、去重操作(也就是你观察到的unique节点耗时)。
  • 如果class字段上建有索引,分组聚合的性能还能进一步提升,PostgreSQL可以利用索引快速完成分组计算。

注:原SQL的子查询缺失表名和别名,即使补全后,性能也远不如直接分组聚合。

内容的提问来源于stack exchange,提问作者cobdmg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:57:47