📚 학습 범위: 『PostgreSQL 튜닝 기술 상』 4장 Join 168 페이지 까지
1. Outer Table / Inner Table 개념
- Outer Table: Nested Loop 조인에서 바깥 루프를 도는 테이블. 먼저 처리됨.
- Inner Table: 바깥에서 선택된 row에 대해 반복적으로 접근하는 테이블.
EXPLAIN 실행계획에서 먼저 나오는 쪽이 outer, 후순위가 inner로 보면 됨.
2. 실행계획 분석 예시 1 (Nested Loop)
Nested Loop
-> Seq Scan on t1 -- outer
-> Index Scan on t2 -- inner
- t1이 먼저 실행되며 outer, 각 row에 대해 t2를 index scan
- loop 수를 보면 t1은 loop=1, t2는 loop=101 등으로 확인 가능
3. Buffer 정보에서 shared read / written 의미
- shared read: 디스크에서 shared buffer로 로딩된 블록 수
- written: buffer 공간이 부족해서 dirty buffer가 디스크로 flush된 수
- 단순 읽기만 해도 쓰기가 발생할 수 있음 → dirty buffer 교체 때문
4. Materialize 노드
- 작은 inner table 결과를 메모리에 저장 (work_mem) 해 두고 outer loop에서 재사용
- 조건: 작은 테이블, work_mem 내 적재 가능
- 조인 순서에 영향: Materialize가 가능하면 작은 테이블을 inner로 둬서 reuse 유도
실험 결과
- Materialize ON: t2 outer, t1 inner → 효율적
- Materialize OFF: t1 outer, t2 inner → Index Scan 없이 반복 Full Scan, 성능 저하
5. Memoize + Nested Loop Join
개념 요약
- Memoize는 파라미터화된 Index Scan의 결과를 key 기반으로 캐시해서 재사용
- 조건: inner 쿼리가
WHERE t.col = outer.col 형태일 때
실행계획 예시
Nested Loop
-> Seq Scan on bizpl_sale_sum b -- outer
-> Memoize
-> Index Scan on product a -- inner
b.prod_id 값이 반복되므로 product 테이블에 대한 결과를 Memoize 노드가 캐시
- 73,200개 row 중 200번만 Index Scan → 나머지는 캐시 재활용
6. Memoize 통계 해석
| 항목 | 의미 |
|---|
| Cache Key | 캐시 키로 사용된 파라미터 (ex. b.prod_id) |
| Hits | 캐시 재사용된 횟수 |
| Misses | 실제로 Index Scan 한 횟수 |
| Memory Usage | 캐시 저장에 사용된 메모리량 |