- Authors
- Name

문제 정의
PostgreSQL 튜닝 실패의 80%는 인덱스 추가가 아니라 통계/쿼리패턴/오토백업 관리 부재에서 발생한다.
아키텍처/원리
- 인덱스는 읽기 성능과 쓰기 비용의 교환이다.
- EXPLAIN ANALYZE와 pg_stat_statements를 함께 봐야 한다.
- 버전 업그레이드(예: 17)는 planner 변화 검증이 필수다.
구현 예시 1
postgresql:
shared_buffers: 8GB
work_mem: 64MB
effective_cache_size: 24GB
random_page_cost: 1.1
구현 예시 2
def choose_index(query_type:str)->str:
if query_type=="prefix_search":
return "btree"
if query_type=="json_filter":
return "gin"
return "brin"
구현 예시 3
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders
WHERE user_id = 42
AND created_at >= now()-interval '30 days'
ORDER BY created_at DESC
LIMIT 50;
구현 예시 4
apiVersion: batch/v1
kind: CronJob
metadata:
name: pg-maintenance
spec:
schedule: '0 3 * * *'
jobTemplate:
spec:
template:
spec:
containers:
- name: vacuum
image: postgres:17
command: ['psql', '-c', 'VACUUM (ANALYZE);']
운영 팁
- 신규 인덱스는
hypopg로 가상 검증 후 생성한다. - bloat/자동 vacuum 지연을 주기 점검한다.
- pg_upgrade 전후 핵심 쿼리 리플레이를 자동화한다.
트러블슈팅
- 인덱스가 있는데 Seq Scan: 통계 stale, 조건 선택도 낮음, 함수 래핑 확인.
- 업그레이드 후 느려짐: planner 파라미터/통계 재수집 필요.
- 락 경합: long transaction 제거, 인덱스 생성은 CONCURRENTLY 사용.
체크리스트
- 상위 N개 느린 쿼리 식별
- 인덱스 후보 가상 검증
- vacuum/analyze 주기 확인
- 업그레이드 리허설
- 롤백 플랜 준비
결론
PostgreSQL 성능은 “인덱스 많이”가 아니라 “워크로드에 맞는 플래너 입력”을 만드는 작업이다.