Hacker News인프라 · 데브옵스오늘의 주요

PostgreSQL의 SELECT DISTINCT, 행 수에 비례해 느려진다

원제 Postgres SELECT DISTINCT Does Not Scale

102 포인트댓글 28
Key Point

쿼리 최적화나 데이터베이스 성능에 의존하는 개발자라면 Postgres의 이 근본적 한계를 알아야 대규모 시스템에서 SELECT DISTINCT를 피할 수 있다.

핵심 요약

  • PostgreSQL의 SELECT DISTINCT는 직관과 달리 인덱스가 아무리 잘 짜여도 항상 조건을 만족하는 모든 행을 풀 스캔한다.
  • 분할된 큐에서 '활성' 파티션을 찾는 쿼리에서 DISTINCT를 썼을 때, 파티션 수가 적어도 초 단위 지연이 발생했다.
  • 같은 파티션 수에서 행 개수만 100에서 1M으로 늘려도 쿼리 시간이 선형으로 증가하는 벤치마크 결과를 확인했다.
  • Postgres는 파티션 수와 무관하게 조건을 만족하는 모든 워크플로우(1M 행)를 스캔해서 세 개의 파티션 키를 찾는 비효율을 보였다.
  • MySQL 같은 다른 데이터베이스는 '느슨한 인덱스 스캔' 연산자로 고유값만 검색하지만, Postgres의 모든 인덱스 스캔 연산자는 전체 조건 행을 읽는다.
  • Postgres 18의 스킵 스캔 최적화도 여전히 모든 조건 행을 스캔하므로 DISTINCT 속도 개선에 쓸 수 없다.
  • 2018년 느슨한 인덱스 스캔 추가 시도는 4년 노력 끝에 폐기됐다.
  • 효율적 해결책은 재귀 CTE를 이용해 각 반복에서 min()만 선택하도록 쿼리를 구성하는 것이다.
  • CTE 방식 쿼리는 파티션 수에 비례한 O(파티션 수) 성능을 보여, 1K에서 1M 행까지 파티션 크기 변화에 지연이 없다.
AI 요약 안내

AI가 한국어로 정리한 내용입니다. 정확한 정보는 원문을 확인해 주세요.

요약 원칙 ↗