
회사 서비스 개발을 하면서, 입사 초기부터 계속 마음에 걸리던 페이지가 하나 있었습니다.
바로 미디어 페이지에서 요소를 불러올 때 로딩이 유난히 느린 문제였습니다.
처음에는 적응하느라 여유가 없어 “나중에 보자” 하고 넘어갔지만, 시간이 생긴 뒤 팀에 이슈를 공유했고 제가 직접 원인을 찾아 해결하기로 했습니다.

처음엔 “파일 서버가 느린 문제”라고 의심했다
우리 서비스는 미디어를 자체 파일 서버로 관리하고 있었고, 미디어 페이지에서 여러 요소를 불러올 때 체감 속도가 확실히 느렸습니다.
그래서 처음 세운 가설은 단순했습니다.
- 파일 서버 조회가 느리다
- 파일 서버 요청이 병목이다
가설을 확인하기 위해 파일 서버로 직접 요청을 보내 응답 시간을 측정했습니다.
그런데 결과는 예상과 달랐습니다.
파일 서버 응답은 충분히 빨랐고,병목은 파일 서버가 아니었습니다.
남는 후보는 API, 그리고 백엔드/DB
파일 서버가 아니라면 이제 의심해야 할 지점은 API 응답 지연이었습니다.
우리 팀은 프론트/백 역할이 나뉘어 있었지만, 상황에 따라 프론트도 백엔드 영역을 함께 다루는 구조였고, 저도 직접 백엔드 코드를 열어보기로 했습니다.
확인하면서 정리한 흐름은 이랬습니다.
- 미디어 리스트 조회 API가 느리다
- API 내부에서 DB 조회가 병목일 가능성이 높다
- 특히 조인이 누적되는 형태라면 비용이 급격히 커질 수 있다
병목의 정체: 관계를 따라가며 조인이 누적되는 조회 구조
백엔드를 뜯어보니, 미디어 정보를 가져오기 위해 여러 테이블을 관계로 따라가며 조인이 누적되는 조회 구조가 있었습니다.
구현 의도는 이해가 됐습니다.
- “정규화된 테이블을 ORM으로 자연스럽게 탐색”
- “엔티티 관계를 따라가면 편하게 데이터가 나온다”
다만 실제 운영 환경에서는 문제가 됐습니다.
- 조회 한 번에 조인이 계속 붙고
- 관계를 한 단계 더 따라갈수록 비용이 늘어나고
- 결국 미디어 페이지에서 리스트를 조회할 때마다 큰 비용을 치르는 구조가 되어 있었습니다
DB를 다시 보니, “조인을 안 해도 되는” 케이스였다
여기서 중요한 포인트가 하나 있었습니다.
DB 설계를 다시 확인해보니 필요한 값이 이미 현재 테이블 컬럼에 존재했습니다.
즉,
- 관계를 따라가며 조인을 누적할 필요가 없고
- 필요한 값은 이미 “그 테이블”에 있었고
- 직접 조회로 충분히 해결 가능한 구조였습니다
그래서 방향을 이렇게 바꿨습니다.
제가 한 조치는 단순합니다.
- 관계 탐색 기반 조회(조인 누적)
- → 필요한 컬럼을 기준으로 한 직접 조회(조인 최소화/제거)
결과적으로 미디어 리스트 조회 API의 병목이 사라졌고, 페이지 로딩이 체감 수준으로 확 달라졌습니다.

개선 전에는 미디어 리스트 조회 API가 평균적으로 약 3.8초 수준이었고,
개선 후에는 0.03초(30ms) 수준으로 떨어졌습니다.
정리하면:
- API 응답 시간 평균 3.8초 → 0.03초
- 약 99.2% 단축