PostgreSQL 성능 튜닝: ANALYZE vs EXPLAIN ANALYZE 차이점과 활용법

2025. 2. 16. 16:18Database/PostgreSQL

1. 개요

PostgreSQL에서 쿼리 성능을 분석하고 최적화하는 두 가지 주요 도구가 있습니다.

  • ANALYZE: 통계 정보를 수집하여 쿼리 플래너가 최적의 실행 계획을 선택할 수 있도록 지원
  • EXPLAIN ANALYZE: 쿼리를 실제 실행하고, 실행 시간이 얼마나 걸리는지, 어떤 방식으로 수행되는지 분석

이 두 가지는 데이터베이스 성능 튜닝에서 필수적인 역할을 합니다. 이번 포스팅에서는 ANALYZEEXPLAIN ANALYZE의 차이점을 살펴보고, 언제 어떤 도구를 사용해야 하는지 알아보겠습니다.


2. ANALYZE: 통계 정보 업데이트로 쿼리 최적화 📊

ANALYZE란?

ANALYZE는 테이블의 통계를 수집하고 PostgreSQL의 쿼리 플래너(Query Planner) 가 최적의 실행 계획을 선택할 수 있도록 돕습니다.

주요 특징

  • 데이터 자체를 분석하지 않고, 테이블 및 인덱스의 통계 정보를 업데이트
  • 쿼리 실행 없이 실제 데이터 크기, NULL 비율, 데이터 분포도 등을 저장
  • 쿼리 실행 계획에 영향을 주지만, 직접적으로 실행 시간은 측정하지 않음
  • 대량의 INSERT, UPDATE, DELETE 후 실행해야 효과적

ANALYZE 사용법

ANALYZE; -- 데이터베이스 내 모든 테이블의 통계 정보 갱신
ANALYZE user; -- 특정 테이블(user)의 통계 정보만 갱신
ANALYZE VERBOSE user; -- 자세한 로그 출력

ANALYZE 실행 전후 비교

EXPLAIN SELECT * FROM user WHERE email = 'a@a.com';

통계를 최신 상태로 유지하지 않으면, PostgreSQL이 비효율적인 실행 계획을 선택할 수도 있음

ANALYZE 실행 후 통계 정보가 업데이트되면서 더 효율적인 인덱스 스캔이 가능해짐

ANALYZE user;

ANALYZE 실행 후 다시 실행하면, 보다 최적화된 실행 계획을 선택할 가능성이 높아짐


3. EXPLAIN ANALYZE: 실제 쿼리 실행 시간 분석

EXPLAIN ANALYZE란?

EXPLAIN ANALYZE쿼리를 직접 실행하고, 실행 계획 및 실행 시간을 분석하는 도구입니다.

주요 특징

  • 쿼리를 실행하면서 실제 실행 시간과 사용된 스캔 방식(시퀀셜 vs 인덱스)을 제공
  • 실행된 모든 단계의 시간 측정 가능
  • JOIN, 서브쿼리, 인덱스 활용 여부를 분석하는 데 필수적
  • 단점: 실제 데이터를 조작하는 UPDATE, DELETE에서 사용 시 데이터 변경이 일어남

EXPLAIN ANALYZE 사용법

EXPLAIN ANALYZE SELECT * FROM user WHERE email = 'a@a.com';

실행 결과 예시

Index Scan using idx_user_email on "user"  (cost=0.14..8.15 rows=1 width=91)
(actual time=0.009..0.011 rows=1 loops=1)
  Index Cond: ((email)::text = 'a@a.com'::text)
Planning Time: 0.193 ms
Execution Time: 0.033 ms

EXPLAIN ANALYZE 결과 해석

  1. Index Scan using idx_user_email인덱스를 사용했음을 의미 (시퀀셜 스캔이 아님)
  2. Actual time=0.009..0.011 → 쿼리 실행 시간이 0.009~0.011ms로 매우 빠름
  3. Execution Time: 0.033 ms → 쿼리의 전체 실행 시간 (실제 수행 결과 포함)

즉, EXPLAIN ANALYZE를 통해 인덱스가 실제로 사용되었는지, 실행 시간이 어느 정도인지 확인할 수 있음


4. ANALYZE vs EXPLAIN ANALYZE 차이점 비교

ANALYZE EXPLAIN ANALYZE
주요 기능 테이블 통계 정보 업데이트 쿼리를 실행하여 실제 실행 시간 분석
쿼리 실행 여부 ❌ 실행되지 않음 ✅ 실제 실행됨
쿼리 플래너 최적화 ✅ 영향 있음 (쿼리 플래너에 반영) ❌ 직접적인 영향 없음
인덱스 활용 여부 분석 ❌ 불가능 ✅ 가능
실제 실행 시간 확인 ❌ 불가능 ✅ 가능
데이터 변경 가능성 ❌ 없음 ⚠️ UPDATE, DELETE 실행 시 주의 필요

언제 ANALYZE를 사용해야 할까?

  • 대량의 데이터 변경(INSERT, UPDATE, DELETE) 후
  • 통계 정보가 오래된 경우
  • 쿼리 플래너가 비효율적인 실행 계획을 선택할 때

언제 EXPLAIN ANALYZE를 사용해야 할까?

  • 쿼리 성능이 느려진 이유를 찾을 때
  • 인덱스가 제대로 활용되는지 확인할 때
  • JOIN 최적화가 필요한 경우

5. 실제 사례: 인덱스 적용 후 성능 비교

인덱스 추가 전 (ANALYZE 실행 후)

Seq Scan on "user"  (cost=0.00..1.12 rows=1 width=91)
(actual time=0.010..0.013 rows=1 loops=1)
Execution Time: 0.033 ms

시퀀셜 스캔(Seq Scan) 사용 → 전체 테이블을 탐색하므로 성능 저하

인덱스 추가 후

CREATE INDEX idx_user_email ON "user" (email);
ANALYZE user;
Index Scan using idx_user_email on "user"  (cost=0.14..8.15 rows=1 width=91)
(actual time=0.009..0.011 rows=1 loops=1)
Execution Time: 0.033 ms

Index Scan 활용 → 시퀀셜 스캔보다 훨씬 빠른 쿼리 실행 가능


6. 결론 및 최적화 전략

  • ANALYZE쿼리 플래너를 최적화하는 역할 (데이터 변경 후 실행 필수)
  • EXPLAIN ANALYZE쿼리 실행을 분석하고 최적화하는 역할
  • 인덱스가 적절하게 사용되는지 EXPLAIN ANALYZE로 확인 후 필요하면 추가
  • 정기적인 VACUUM ANALYZE 실행으로 성능 유지