Postgres 的 SELECT DISTINCT 为何无法扩展?
Postgres SELECT DISTINCT Does Not Scale

尽管 Postgres 常被推崇为全能数据库,但我们在处理分区队列工作负载时发现了一个反直觉的性能陷阱:SELECT DISTINCT 查询。即使建立了完美的索引,该查询依然会扫描所有匹配的行,导致性能随数据量线性下降,而非预期的按分区数量增长。本文基于 DBOS 团队的实战经验,深入剖析了 Postgres 内部设计导致这一问题的根本原因,并提供了切实可行的优化方案,帮助开发者避开这一隐蔽的性能瓶颈。
SELECT DISTINCT 是一个看似无害的条款,但其性能特征却出乎意料:无论你如何建立索引,也无论需要检索的唯一值有多少,它始终会扫描所有匹配其谓词的每一行。
HN 评论区
28- nattaylor
Loose index scan 就是为这个场景而生的 https://dev.mysql.com/doc/refman/8.0/en/group-by-optimizatio...
Postgres 目前还没有 https://wiki.postgresql.org/wiki/Loose_indexscan
- procaryote
我通常把使用 SELECT DISTINCT 视为一个警示信号,因为这往往意味着代码写得不好。
有些人用它是因为不懂唯一性约束,试图在查询后补救;有些人是因为忘了 join 条件,纯属新手;还有些人是因为它曾经帮他们解决过一个问题,结果现在到处都加上。
在我看来,这类人远多于那些经过深思熟虑才使用 SELECT DISTINCT 的人。
- sandeepkd
文章里说这家公司是由 Postgres 的创始人联合创立的。我很难相信这一点,因为这篇文章并没有什么新意,对他们来说可能只是重新发现。我理解每个人都要经历自己的学习过程,但另一方面,既然在经营公司,寻求专业帮助并不是什么坏主意。
根据我的经验,这类查询无论如何都无法扩展。不过,如果你已经在这条路上投入了很多,那就雇佣一个 DBA;如果还没走太远,那就雇佣一位架构师来重新设计数据模型以提升性能。