728x90
※ PostgreSQL: Cache Hit (shared hit).
안녕하세요. 듀스트림입니다.
오늘 포스팅은 성능 관점 지표에서 매우 중요한 캐시 히트에 관한 내용입니다.
1. 캐시 히트란?
Shared Buffer Cache 안에서 이미 로드되어 있는 페이지를 다시 읽은 횟수입니다.
즉, 디스크로부터 읽지 않고 메모리 내 캐시 버퍼에서 재사용된 페이지를 의미합니다.
그래서 "캐시 히트율이 높다"는 말은 디스크 I/O 없이 대부분의 데이터를 메모리에서 읽고 있다는 의미이며, 성능상으로 매우 좋은 현상입니다. (OLTP에서는 98% 이상을 목표로 합니다.)
실행계획에서는 shared hit로 출력됩니다.
2. 캐시 히트율이 높을 때 가능한 해석
| 관점 | 캐시 히트율 높음의 의미 | 해석 |
| DB 성능 관점 | 디스크 I/O를 거의 하지 않음. 대부분 캐시에 있음. | ✅ 성능 좋음 (I/O 대기 없음) |
| 워크로드 패턴 관점 | 동일한 데이터 페이지를 반복해서 읽는 쿼리 많음. | ⚠️ 캐시 재사용 높지만, 특정 페이지에 쏠림 가능 |
| 애플리케이션 접근 패턴 | 자주 조회되는 “핫 데이터”가 잘 캐싱됨. | ✅ 정상적 현상 (OLTP 시스템) |
| 쿼리 구조 관점 | 같은 페이지를 반복 스캔하거나 중복 조인. | ⚠️ 불필요한 반복 접근일 수도 있음 |
| 시스템 캐시 크기 관점 | shared_buffers가 충분히 커서 대부분의 테이블이 상주. | ✅ 메모리 효율적 (적정 크기일 경우) |
| 반대 현상과 대비 | hit ↓ / read ↑ → 캐시 미스(I/O 증가). | 🚨 튜닝 필요 (I/O 병목) |
3. 캐시 히트율이 높아지는 주요 원인
| 원인 | 설명 | 성격 |
| 자주 읽는 테이블 (핫셋) | 동일 테이블/인덱스 일부만 집중적으로 읽힘. | ✅ 좋은 캐시 효과 |
| 반복 실행 쿼리 | 같은 조건/파라미터로 반복 조회. | ✅ 효율적 |
| Nested Loop 조인 반복 접근 | 내부 테이블을 같은 키로 반복 접근. | ⚠️ 구조적 중복 가능 |
| 캐시 크기 충분 (shared_buffers) | 전체 데이터셋이 메모리에 상주. | ✅ 캐시 효율 좋음 |
| 인덱스-only 스캔 | 인덱스만으로 처리 → 대부분 캐시에서 해결. | ✅ 긍정적 |
| temp/seq scan 반복 | 루프 안에서 같은 테이블 반복 full scan. | ⚠️ 캐시 hit은 높지만, CPU 낭비 가능 |
4. 캐시 히트율 계산 쿼리
SELECT
blks_hit,
blks_read,
round(100.0 * blks_hit / (blks_hit + blks_read), 2) AS cache_hit_ratio
FROM pg_stat_database
WHERE datname = current_database();

→ 디스크 리드는 5.12%이고, 94.88%는 메모리에서 처리했다는 의미입니다.
5. 캐시 히트율이 높지만 문제인 케이스
| 문제 상황 | 설명 |
| Nested Loop 반복 스캔 | 동일한 작은 인덱스 페이지를 수십만 번 반복 접근 → hit 폭증, CPU 낭비 |
| 카디널리티 오차 | 플래너가 조인 순서 잘못 선택 → 작은 쪽을 바깥 루프로 돌림 → 캐시 hit만 많고 전체 느림 |
| 락 대기/동시성 병목 | hit 높지만 CPU 시간 대부분은 락 대기 |
| shared_buffers 과도하게 큼 | 캐시 유지에 CPU/메모리 리소스 낭비, dirty page flush 지연 가능 |
"캐시 히트율이 높다 = Disk I/O는 적다"까지는 맞지만, CPU 효율은 또 다른 문제입니다.
6. 실행계획 지표 해석 방법
| 지표 | 좋은 기준 | 해석 포인트 |
| Buffers: hit/read 비율 | 약 1000:1 이상 | 디스크 I/O 최소화 |
| Buffers total (hit+read) | 너무 높으면 Loop/조인 구조 의심 | CPU 과부하 가능 |
| read 비율 높음 | shared_buffers 부족 / 랜덤 접근 많음 | I/O 병목 가능 |
캐시 히트가 높다는 건,
- 디스크 I/O 없이 메모리에서 데이터를 읽고 있다.
- 동일한 페이지를 여러 번 읽는 쿼리가 많다.
- 데이터 접근 패턴이 “작은 범위 반복 접근”일 수 있다.
- 캐시 효율은 좋지만 CPU 효율까지 보려면 Buffers + Execution Time을 함께 분석해야 한다.
정도로 정리할 수 있습니다.
오늘은 여기까지~
728x90
'PostgreSQL' 카테고리의 다른 글
| PostgreSQL: Heap Fetch (0) | 2025.11.03 |
|---|---|
| PostgreSQL: ALTER TABLE ... (0) | 2025.10.31 |
| PostgreSQL: Merge Join (0) | 2025.10.22 |
| PostgreSQL: ERROR [40001]: canceling statement due to conflict with recovery (0) | 2025.10.20 |
| PostgreSQL: Skip Locked (0) | 2025.09.17 |