Postgres の SELECT DISTINCT はインデックスがあっても全行をスキャンする
Postgres SELECT DISTINCT Does Not Scale

Postgres の SELECT DISTINCT は、一見するとシンプルで高速に思えるが、実際にはインデックスの有無やユニーク値の数に関係なく、条件に一致するすべての行をスキャンしてしまう。DBOS がパーティション化されたキューでこの問題に直面し、最も単純なクエリが最も高コストになった事例を解説。Postgres の設計上の判断と回避策を紹介する。
SELECT DISTINCT は一見無害な句で、カラムのすべてのユニーク値を取得する。しかしそのパフォーマンス特性は予想外だ。テーブルをどうインデックスしても、取得するユニーク値がどれほど少なくても、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 の使用を警告フラグとして扱うようになった。というのも、それが悪いコードを示していることが非常に多いからだ
ある人々は一意性制約を理解しておらず、後からいわば修正しようとして使う。ある人々は結合条件を忘れて、まったくの素人だから使う。ある人々は一度問題を解決してくれたから、今ではどこにでも追加する
こうした人々は、SELECT DISTINCT をよく考えて使う人々を数で上回っているようだ
- sandeepkd
その会社は Postgres の創設者によって共同設立されたと書いてある。記事に目新しいものは何もなく、おそらく彼らにとっては発見だったことを考えると、その点は信じがたい。誰もがこうしたことを学ぶために自分自身の道のりを歩まなければならないのは理解しているが、同時にビジネスを運営しているなら専門家の助けを求めるのは悪い考えではない。
私の経験に基づくと、このようなクエリは何をしてもスケールしない。しかし、もしすでにそのようなクエリに多大な投資をしてきた道にいるなら、DBA を雇うべきだ。まだ遠くないなら、より良いパフォーマンスのためにデータをモデル化するアーキテクトを雇うべきだ。