사이드 프로젝트

개인 운영 프로젝트 N + 1 문제 해결로 1900ms → 543ms로 70% 성능 개선

랑 이 2026. 1. 18. 23:43
반응형

개인적으로 게임 관련 사이트를 운영 중인데 서비스를 이용하면서 특정 API의 응답이 체감상 다소 느리다는 느낌을 받았다

실제로 어느 정도 지연이 발생하고 있는지 확인하기 위해 PostMan을 통해 배포 서버에 요청을 보내 API 응답 시간을 측정해 봤다

 

그 결과, 문제가 된 API의 평균 응답 속도 1900ms으로 확인되었고 자주 조회되는 API임을 고려했을 때 개선이 필요하다고 판단했다

서버 환경 및 인프라 구성

해당 프로젝트는 다음과 같은 환경에서 운영 중이다

  • AWS EC2 (프리티어)
    • 인스턴스 타입: t2.micro 
    • 메모리(RAM): 약 2GB (가상메모리 포함)
    • 운영체제: Linux
  • AWS RDS 사용 (관계형 데이터베이스)
  • Cloudflare CDN을 앞단에 적용하여
    • 정적 리소스 캐싱
    • HTTPS 및 기본적인 네트워크 최적화 수행

원인 파악

초기 개발 단계에서는 기능 구현에 집중하다 보니 성능 측면에서 놓친 부분이 있을 수 있다고 판단했다.

 

이에 배포 서버의 로그와 Hibernate 쿼리 로그를 확인하던 중,

해당 API 요청 시 쿼리가 끊임없이 반복적으로 실행되고 있는 현상을 발견했다

 

배포 서버의 로그에 쿼리가 끊이질 않는 걸 보고 N + 1 문제가 아닐까 생각했다

내부 로직 쿼리를 자세히 분석한 결과 연관 엔티티 조회 과정에서 N + 1 문제가 발생하고 있는 걸 확인했다

개선 방법

비공개 프로젝트 특성상 내부 도메인 로직에 대한 상세한 설명은 어렵습니다

 

제 해결을 위해 Repository 조회 쿼리에 fetch join을 적용한 JPQL을 작성하여

연관 엔티티를 단일 쿼리로 한 번에 로딩하도록 개선했다

 

이번 개선을 통해 전형적인 N + 1 문제를 해결했을 때 어느 정도 성능 개선을 기대할 수 있을지 확인해보고 싶었다

그리고 많은 유저가 사용했을 때는 N + 1 문제는 DB에 치명적인 부하를 줄 수 있기 때문에 반드시 해결해야 했다

개선 결과

fetch join 적용 이후 동일한 API의 응답 속도를 다시 측정한 결과

- 개선 전: 1900ms

- 개선 후: 약 543ms

약 70% 이상 응답 시간 단축이라는 의미 있는 성능 개선을 경험할 수 있었다

 

프리티어 인프라 환경에서도 쿼리 구조 개선만으로 체감 성능을 크게 향상할 수 있었고 

ORM 사용 시 쿼리 흐름을 파악하는 게 얼마나 중요한지 다시 한번 느낄 수 있었다

반응형