Postgres SELECT DISTINCT 확장되지 않는다
(dbos.dev)
Postgres의 SELECT DISTINCT 연산이 인덱스 존재 여부와 상관없이 데이터 양에 따라 성능이 선형적으로 저하되는 구조적 문제를 분석하며, 이는 대규모 시스템 설계 시 치명적인 병목이 될 수 있음을 경고합니다.
이 글의 핵심 포인트
- 1Postgres의 SELECT DISTINCT는 인덱스가 있어도 조건에 일치하는 모든 행을 스캔함
- 2데이터가 'Wide but Shallow'(많은 파티션, 적은 행)일 때는 잘 작동하지만, 'Narrow but Deep'(적은 파티션, 많은 행)일 때 성능이 선형적으로 저하됨
- 3MySQL은 'Loose Index Scan'을 통해 고유 값만 빠르게 찾을 수 있는 기능을 제공함
- 4Postgres 18에 도입된 'Skip Scan'은 다중 컬럼 인덱스의 특정 상황에만 적용되며 SELECT DISTINCT 문제를 완전히 해결하지 못함
- 5쿼리 성능이 데이터의 고유 값 개수가 아닌, 전체 데이터 행 수에 비례하여 악화됨
이 글에 대한 공공지능 분석
왜 중요한가?
데이터베이스의 성능은 서비스 확장성의 핵심입니다. 단순해 보이는 SQL 구문이 데이터 규모에 따라 예상치 못한 성능 저하를 일으킬 수 있다는 사실은, 시스템 아키텍처 설계 시 인덱스 설계만큼이나 실행 계획(Execution Plan)에 대한 이해가 필수적임을 시사합니다.
어떤 배경과 맥락이 있나?
현대적인 분산 시스템이나 메시지 큐 워크로드에서는 효율적인 파티셔닝이 중요합니다. 개발자들은 보통 인덱스가 있으면 쿼리가 효율적일 것이라 가정하지만, Postgres의 특정 연산자는 인덱스를 활용해 '건너뛰기'를 하는 대신 모든 데이터를 확인하는 방식을 취하고 있습니다.
업계에 어떤 영향을 주나?
이러한 문제는 클라우드 기반 DB를 사용하는 기업들에게 예상치 못한 인프라 비용 상승과 서비스 지연을 초래합니다. 특히 MySQL처럼 'Loose Index Scan'을 지원하는 엔진과 비교했을 때, Postgres 기반의 대규모 트래픽 처리 시스템은 쿼리 최적화를 위해 더 복잡한 우회 전략을 설계해야 하는 부담을 안게 됩니다.
한국 시장에 어떤 시사점이 있나?
빠른 성장을 목표로 하는 한국의 많은 스타트업은 초기에는 단순한 쿼리로 시작하지만, 트래픽이 급증하는 'Deep'한 데이터 구조에 직면했을 때 심각한 장애를 겪을 수 있습니다. 따라서 초기 설계 단계부터 쿼리 패턴의 확장성을 검증하고, DB 엔진의 한계를 극복할 수 있는 애플리케이션 레벨의 최적화 전략을 준비해야 합니다.
이 글에 대한 큐레이터 의견
개발자들에게 `SELECT DISTINCT`는 가장 직관적이고 편리한 도구입니다. 하지만 이 글이 보여주듯, '편리함'은 종종 '비효적성'과 맞바꾼 대가일 수 있습니다. 데이터가 적을 때는 문제가 없다가, 특정 파티션에 데이터가 쌓이는 순간(Narrow but Deep) 시스템 전체의 병목으로 돌변하는 특성은 전형적인 '기술 부채'의 형태를 <0xEB><0x9D><0xB1>니다.
물론 반론도 가능합니다. 모든 쿼리를 최적화된 방식으로 작성하는 것은 개발 생산성을 저하시키며, 데이터 규모가 통제 가능한 범위 내에 있다면 `SELECT DISTINCT`를 사용하는 것이 코드의 가독성과 유지보수 측면에서 훨씬 유리합니다. 무조건적인 최적화보다는 서비스의 성장 단계에 맞춘 접근이 필요합니다.
따라서 스타트업 창업자와 리드 개발자는 쿼리의 '가독성'과 '확장성' 사이의 트레이드오프를 명확히 인지해야 합니다. 쿼리 성능이 임계점에 도달하기 전에 `EXPLAIN ANALYZE`를 통해 실행 계획을 주기적으로 모니터링하고, 필요하다면 애플리케이션 레벨에서 중복을 제거하거나 별도의 집계 테이블을 운영하는 등의 선제적인 아키텍처 대응 전략을 수립해야 합니다.
관련 뉴스
댓글
아직 댓글이 없습니다. 첫 댓글을 남겨보세요.