2026.03.17 - [Spring 2기 과제] - 조회 API 응답 속도가 느린 이유 분석 (Postman 테스트 기반)
조회 API 응답 속도가 느린 이유 분석 (Postman 테스트 기반)
문제 상황 식당 / 메뉴 / 리뷰 조회 API를 구현한 뒤 더미데이터를 `data.sql`로 넣고 Postman을 통해 테스트를 진행하였다.처음에는 단순히 정상 조회 여부만 확인하려 했지만 여러 번 호출하는 과정
sudaruuu.tistory.com
2026.03.17 - [분류 전체보기] - 조회 성능 개선 1단계 - Pageable 적용
조회 성능 개선 1단계 - Pageable 적용
2026.03.17 - [Spring 2기 과제] - 조회 API 응답 속도가 느린 이유 분석 (Postman 테스트 기반) 조회 API 응답 속도가 느린 이유 분석 (Postman 테스트 기반)문제 상황 식당 / 메뉴 / 리뷰 조회 API를 구현한 뒤
sudaruuu.tistory.com
문제 상황
Pageable을 적용한 이후
조회 API 응답 시간이
약 121ms → 77ms로 개선된 것을 확인하였다.
하지만 여전히 문제가 있었다.
동일한 조회 요청을 반복할 경우에도
매번 DB에 접근이 발생한다는 점이었다.
특히 식당 / 메뉴 / 리뷰 조회처럼
조회 비중이 높은 API의 경우
👉 반복 조회 시 DB 부하가 계속 발생하는 구조였다.
원인 분석
Pageable은
- 조회 데이터 양을 줄이는 데는 효과적이지만
- 반복 조회를 줄여주지는 못한다
즉,
👉 조회량은 줄였지만, 조회 횟수는 그대로였다
이로 인해 동일한 요청이 반복될 경우
DB에 계속 접근하는 비효율이 발생하고 있었다.
해결 과정
반복 조회 시 DB 접근을 줄이기 위해
Spring Cache를 적용하였다.
단건 조회
@Cacheable(value = "store", key = "#storeId")
@Transactional(readOnly = true)
public StoreResponse getStore(Long storeId) {
Store store = findStoreById(storeId);
return StoreResponse.from(store);
}
목록 조회
@Cacheable(value = "stores", key = "#keyword + '-' + #pageable.pageNumber + '-' + #pageable.pageSize")
@Transactional(readOnly = true)
public Page<StoreResponse> getStores(String keyword, Pageable pageable) {
...
}
데이터 변경 시 캐시 제거
@Caching(evict = {@CacheEvict(value = "stores", allEntries = true), @CacheEvict(value = "store", key = "#storeId")})
public void updateStore(...) {
...
}
결과
캐시 적용 후 테스트 결과
| 단계 | 응답 시간 |
| 기존 | 121ms |
| Pageable | 77ms |
| Cache 적용 | 7ms |
👉 반복 조회 시 DB 접근 없이
캐시에서 바로 데이터를 반환하면서
응답 속도가 크게 개선되었다.
결론
- Pageable → 조회량 감소
- Cache → 반복 조회 제거
👉 두 가지를 함께 적용해야
효과적인 성능 개선이 가능하다는 것을 확인하였다.
다음 문제
캐시 적용 과정에서
👉 DTO 직렬화 오류 발생 (NotSerializableException)
다음 단계
👉 DTO 직렬화 문제 해결 및
👉 대용량 데이터 환경에서 성능 검증 진행
'트러블슈팅' 카테고리의 다른 글
| 리뷰 좋아요 기능의 DB 직접 반영 구조를 Redis write-back 방식으로 개선한 과정 (0) | 2026.03.18 |
|---|---|
| 캐시 적용 후 DTO 직렬화 문제 해결 및 대용량 데이터 성능 검증 (0) | 2026.03.17 |
| 조회 성능 개선 1단계 - Pageable 적용 (0) | 2026.03.17 |
| 조회 API 응답 속도가 느린 이유 분석 (Postman 테스트 기반) (0) | 2026.03.17 |
| @Transactional(readOnly = true)를 조회 로직에서 사용하는 이유 (0) | 2026.03.11 |