피드로 돌아가기
Debugging PostgreSQL Query Plan Instability in Production
Dev.toDev.to
Database

PostgreSQL 옵티마이저가 상관관계가 있는 불린 컬럼 6개의 통계값을 독립적으로 곱셈하여 14배 성능 저하를 유발했다

Debugging PostgreSQL Query Plan Instability in Production

Sriram Rajendran2026년 3월 31일16advanced

Context

PostgreSQL 14 기반 필드 기술자 배차 시스템에서 오전 10시에 3ms로 실행되던 쿼리가 오후 2시에 42ms로 악화됨. 6개 불린 컬럼(is_active, is_available, is_dispatched, is_blocked, is_express_enabled, is_suspended)이 시간대별 상관관계를 형성하여 쿼리 계획이 변경됨. Composite index가 이미 존재했으나 통계 추정 단계에서는 해당 인덱스를 참조하지 않음.

Technical Solution

  • 테이블 구조 변경 없이 기존 불린 컬럼 조합의 빈도 분포를 pg_statistic에서 분석
  • EXPLAIN ANALYZE로 estimated rows와 actual rows 간 10배 이상 편차를 확인
  • 상관관계가 존재하는 불린 컬럼 조합을 단일 ENUM 타입으로 설계 변경 검토
  • pg_stats 뷰에서 MCV, histogram을 확인하여 컬럼 간 의존성 검증
  • 히스토그램 버킷 수 증가로 세밀한 통계 수집 환경 구성

Impact

동일 쿼리에서 14배レイテンシ (3ms → 42ms). 필드 기술자 15,000명 중 약 8,700명이 복합 조건에 해당했으나 옵티마이저는 38명을 추정함.

Key Takeaway

PostgreSQL의 통계 추정 단계는 인덱스 존재 여부와 무관하게 pg_statistic의 독립 컬럼 통계를 곱셈한다. 상관관계가 존재하는 컬럼 조합은 ENUM 또는 조건 표현식으로 단일 상태로 정의해야 한다.


복수 불린 컬럼 간에 상관관계가 존재하는 환경에서 PostgreSQL cost-based optimizer의 추정 오차를 줄이려면 컬럼 조합을 ENUM 타입으로 전환하여 planner가 조합별 실제 빈도를 참조하도록 설계해야 한다

원문 읽기