PostgreSQL · 2026-03-16

PostgreSQL 인덱스 통계와 ANALYZE 이해하기

PostgreSQL 인덱스 통계의 개념과 pg_stats·pg_stat_user_indexes 조회 방법, ANALYZE 실행 기준과 실무 적용 사례를 초보자 관점에서 정리한 기술 자료

작성일 : 2026-03-16 ㆍ 작성자 : 관리자
post
목차

개요

쿼리 성능을 개선하려면 통계의 역할을 이해하는 것이 중요하다. PostgreSQL은 실행 계획을 만들 때 통계 정보를 사용한다. 특히 인덱스와 관련된 통계는 옵티마이저가 효율적인 접근 경로를 선택하는 데 큰 영향을 준다. 이 글에서는 pg_stats와 관련 뷰를 통해 통계를 확인하는 방법과 ANALYZE 명령의 사용 시점을 실무 관점에서 설명한다.

PostgreSQL 통계의 기본 개념

통계의 목적

통계는 테이블의 데이터 분포를 요약한다. 옵티마이저는 이 요약을 바탕으로 행 수 추정, 조인 방식, 인덱스 사용 여부를 결정한다. 잘못된 통계는 잘못된 계획으로 이어져 성능 저하를 유발한다.

주요 통계 항목

  • n_distinct: 고유값 수 추정
  • null_frac: NULL 비율
  • most_common_vals: 자주 등장하는 값 목록
  • histogram_bounds: 값 분포의 구간 경계
  • correlation: 물리적 정렬과 값 분포의 상관 관계

통계 조회: pg_stats와 pg_stat_user_indexes

PostgreSQL은 여러 뷰를 제공한다. pg_stats는 칼럼별 통계 요약을 보여준다. pg_stat_user_indexes 등은 인덱스의 사용 통계를 제공한다. 두 뷰를 조합하면 인덱스 효율을 판단할 수 있다.

pg_stats 조회 예시

SELECT schemaname, tablename, attname, n_distinct, null_frac, most_common_vals
FROM pg_stats
WHERE tablename = 'orders' AND schemaname = 'public';

결과에서 n_distinct와 histogram_bounds를 확인하면 선택성(selectivity)을 파악할 수 있다. most_common_vals는 특정 값에 쏠림 현상이 있는지 보여준다.

인덱스 사용 통계 확인

SELECT schemaname, relname AS table, indexrelname AS index, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE relname = 'orders';

idx_scan은 인덱스가 사용된 횟수를, idx_tup_fetch는 실제로 인덱스 통해 읽은 행 수를 나타낸다. 이를 통해 인덱스가 실무에서 유의미하게 사용되는지 판단한다.

ANALYZE의 역할과 실행 시점

ANALYZE는 테이블의 샘플링을 통해 통계를 갱신한다. VACUUM과 함께 사용되기도 하지만 ANALYZE만 단독으로 실행할 수 있다. 통계가 오래되면 옵티마이저의 추정이 빗나가므로 주기적 갱신이 필요하다.

언제 ANALYZE를 실행해야 하는가

  • 대량의 INSERT/UPDATE/DELETE가 발생한 후
  • 데이터 분포가 크게 변한 경우
  • 테이블 구조 변경(칼럼 추가 등) 후
  • 쿼리 계획이 갑자기 나빠진 경우

ANALYZE 실행 예시

ANALYZE public.orders;
-- 또는 데이터베이스 전체를 갱신
ANALYZE;

특정 칼럼만 갱신하려면 칼럼명을 지정할 수 있다. 통계 샘플링 크기는 default_statistics_target 설정으로 조정 가능하다. 값이 클수록 더 정밀하지만 처리 시간이 증가한다.

실무 적용과 모범 사례

모니터링 절차

  • 정기적으로 pg_stat_user_tables와 pg_stat_user_indexes 확인
  • 특정 쿼리의 계획이 비정상적이면 pg_stats로 해당 칼럼 확인
  • 데이터 변경량이 크면 자동화된 ANALYZE 트리거 도입

통계 세부 조정

default_statistics_target을 높여 특정 칼럼의 통계를 더 정밀하게 만들 수 있다. 예컨대 WHERE 절에 자주 쓰이는 칼럼은 ALTER TABLE ... ALTER COLUMN ... SET STATISTICS로 타겟을 증가시킨다. 다만 설정 값이 지나치면 ANALYZE 비용이 커진다.

인덱스 관련 실무 팁

  • 인덱스 사용 빈도가 낮으면 제거를 검토
  • 복합 조건에서는 통계 기반으로 인덱스 순서와 조합을 판단
  • 정렬된 입력이 많으면 correlation 값을 확인해 인덱스 효율을 예측

문제 해결 예시

예상과 다른 계획이 선택될 때의 접근법은 다음과 같다.

  • 문제 쿼리의 EXPLAIN ANALYZE 실행
  • 관련 칼럼을 pg_stats로 조회해 분포 확인
  • 필요 시 ANALYZE 수행 후 계획 변화 확인
-- 문제 원인 진단 절차 예시
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE status = 'pending';
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename='orders';
ANALYZE public.orders;
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE status = 'pending';

마무리

통계는 옵티마이저의 핵심 정보원이다. pg_stats와 pg_stat_user_indexes를 통해 현재 상태를 파악하고, 필요할 때 ANALYZE로 갱신하면 안정적인 쿼리 성능을 유지할 수 있다. 설정과 실행 빈도는 시스템 특성에 맞춰 조정하는 것이 중요하다.

analyze postgres 사용법 인덱스 통계 postgres 확인 postgres pg_stats 활용 PostgreSQL 통계 pg_stat_user_indexes ANALYZE 실행 쿼리 옵티마이저 통계 튜닝