한양과학기술고등학교

에듀테크 프로젝트 대시보드

EXPLAIN 읽기

EXPLAIN ANALYZE BUFFERS Seq Scan Nested Loop rows

플래너가 쿼리를 어떻게 실행할지(계획) 와 실제로 어땠는지 를 보여줍니다. 튜닝의 출발점.

1. 두 가지 모드

EXPLAIN SELECT ...;                       -- 추정만 (실행 안 함)
EXPLAIN (ANALYZE, BUFFERS) SELECT ...;    -- 실제 실행 + 시간·버퍼

-- 쓰기 쿼리를 ANALYZE 하려면 롤백으로 감싸기
BEGIN;
EXPLAIN (ANALYZE) UPDATE ...;
ROLLBACK;

2. 출력 예

Index Scan using idx_exams_student on exams  (cost=0.29..8.31 rows=2 width=12) (actual time=0.02..0.03 rows=2 loops=1)
  Index Cond: (student_id = 42)
  Buffers: shared hit=4
Planning Time: 0.1 ms
Execution Time: 0.05 ms
항목뜻
cost=시작..총플래너의 임의 단위 추정 비용
rows (계획) vs rows (actual)추정 행수 vs 실제 행수 — 크게 다르면 통계가 낡음
loops이 노드가 반복 실행된 횟수 (actual time 은 1회분)
Buffers: shared hit / read캐시 적중 / 디스크 읽기 블록 수

3. 스캔·조인 노드

노드언제 좋고 나쁜가
Seq Scan작은 테이블·많은 행이면 정상 / 큰 테이블 소수 행이면 인덱스 부재 신호
Index Scan / Index Only Scan소수 행 조회에 이상적 (Only 는 테이블 접근도 생략)
Bitmap Heap Scan중간 규모 — 여러 인덱스 결과를 모아 한번에
Nested Loop한쪽이 아주 작을 때 / 양쪽 크면 재앙
Hash Join / Merge Join큰 테이블끼리 조인의 정상 선택

4. 나쁜 신호

이런 게 보이면
  • Rows Removed by Filter: 900000 — 인덱스로 걸러야 할 걸 스캔 후 버림
  • 추정 rows=1 인데 actual rows=50000 — ANALYZE 테이블; 실행
  • Sort Method: external merge Disk: 82MB — work_mem 부족

시각화: EXPLAIN (ANALYZE, FORMAT JSON) 결과를 explain.dalibo.com 등에 붙여보면 병목이 잘 보입니다.

"정규화로 시작하고, 측정한 뒤에 비정규화하라"