SPRING
[스터디] 취업뽀개기 사이트 (1) _ N+1 문제 개선
연곰2
2025. 7. 13. 19:34
목표
✅기존 코드에서 n+1이 발생하는 지점을 찾아 정리하고,
성능 개선을 위한 다양한 문제 해결 방법을 도입해 비교/테스트하여 가장 최적의 방법 적용해보자!
1. 데이터 추가
데이터 추가 작성 코드 (NotProd.java)
- 상세 코드: https://github.com/chibbotec/k6_test/blob/main/jpa/NotProd.java
- 설정값
- TEST_NUMBER: 50 (기본 엔티티 개수)
- RELATED_DATA_COUNT: 500 (연관 데이터 개수)
- 전체 데이터 요약
테이블명 데이터 개수 비고
TechInterview | 50 | 기본 엔티티 |
Question | 50 | 기본 엔티티 |
ParticipantQnA | 25,000 | Question당 500개 |
Comment | 25,000 | Question당 500개 |
Contest | 50 | 기본 엔티티 |
Participant | 25,000 | Contest당 500개 |
Problem | 25,000 | Contest당 500개 |
Answer | 25,000 | 성능 고려하여 제한적 생성 |
Note | 100 | 공개/비공개 각각 50개 |
총합 | 125,250개 | 전체 레코드 수 |
2. k6 테스트 - 콘테스트 목록
k6 테스트 코드 (contest-api-test.js)
k6_test/jpa/contest-api-test.js at main · chibbotec/k6_test
Contribute to chibbotec/k6_test development by creating an account on GitHub.
github.com
3. K6 시나리오
테스트 개요
- 테스트 대상: Contest 목록 조회 API
- 엔드포인트: GET /api/v1/tech-interview/{SPACE_ID}/contests
- 테스트 유형: 부하 테스트 (Load Testing)
- 인증: 인증 없음 (No Authentication)
부하 테스트 시나리오
- 최대 동시 사용자: 30명
- 테스트 패턴: 점진적 부하 증가 → 유지 → 감소
성능 임계값 (Thresholds)
- 응답시간: 95%의 요청이 1초 이내 완료
- 성공률: 95% 이상 성공률 유지
- HTTP 실패율: 5% 미만
- HTTP 응답시간: HTTP 요청의 95%가 1초 이내
테스트 시나리오 상세
- 연결 테스트: 테스트 시작 전 API 연결 상태 확인
- 환경 검증: Base URL, Space ID 등 환경 변수 확인
- 샘플 응답 검증: JSON 배열 형태의 응답 구조 확인
메인 테스트 로직
각 VU(Virtual User)가 반복 실행하는 작업:
- API 호출: Contest 목록 조회 GET 요청
- 응답 검증:
- HTTP 상태 코드 200 확인
- 응답 시간 1초 이내 확인
- JSON 배열 형태 응답 확인
- Content-Type이 application/json 확인
- 메트릭 수집: 성공/실패 카운트 및 응답시간 기록
- 대기: 0.1~0.6초 랜덤 대기 (서버 부하 분산)
결과 분석 항목
성능 지표
- 처리량: 초당/분당 요청 수
- 응답시간: 평균, 최소, 최대, P50, P90, P95, P99
- 안정성: 성공률, HTTP 실패율
- 리소스: 데이터 송수신량
테스트 결과
- batch_size 적용 전
2025-06-23T16:54:32.312+09:00 INFO 62136 --- [techinterview] [nio-9040-exec-2] i.StatisticalLoggingSessionEventListener : Session Metrics {
2707042 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
6689083 nanoseconds spent preparing 51 JDBC statements;
258081169 nanoseconds spent executing 51 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
3000 nanoseconds spent executing 1 pre-partial-flushes;
2375 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
=========================================================
Contest List API 상세 성능 테스트 결과
=========================================================
🎯 테스트 대상
URL : <http://localhost:9040/api/v1/tech-interview/1/contests>
테스트 유형 : Contest 목록 조회 API
📊 테스트 실행 개요
총 테스트 기간 : 101.18초 (1.7분)
최대 동시 VU 수 : 30개
평균 동시 VU 수 : 0.0개
총 완료된 반복 : 1219회
반복 처리율 : 12.048/초
🎯 API 요청 성능 분석
총 요청 수 : 1219개
성공한 요청 : 1219개 (100.00%)
실패한 요청 : 0개
API 성공률 : 100.00%
📈 처리량 분석
초당 요청 수 : 12.05 req/s
분당 요청 수 : 723 req/min
VU당 평균 요청 : 40.6 req/VU
⏱️ 애플리케이션 응답 시간
평균 (Average) : 1106.39ms
최소 (Min) : 267.00ms
최대 (Max) : 3031.00ms
중앙값 (p50) : 1123.00ms
90th percentile : 1822.00ms
95th percentile : 1927.40ms
99th percentile : 0.00ms
🌐 HTTP 네트워크 성능
총 HTTP 요청 수 : 1220개
HTTP 처리율 : 12.06/초
HTTP 실패율 : 0.00%
🕐 HTTP 응답 시간 분포
평균 : 1105.73ms
최소 : 267.09ms
최대 : 3031.04ms
중앙값 (p50) : 1122.53ms
90th percentile : 1822.51ms
95th percentile : 1927.11ms
99th percentile : 0.00ms
🔧 HTTP 요청 세부 타이밍
연결 설정 시간 : 0.01ms
서버 처리 시간 : 1005.84ms
응답 수신 시간 : 99.85ms
요청 차단 시간 : 0.02ms
📊 데이터 전송량
수신된 데이터 : 2602690.10 KB
전송된 데이터 : 202.54 KB
평균 수신 속도 : 25722.97 KB/s
평균 전송 속도 : 2.00 KB/s
요청당 평균 응답크기: 2186345 bytes
💡 성능 등급 평가
응답시간 (평균) : 🔴 개선필요
응답시간 (95%) : 🟠 보통
안정성 (성공률) : 🟢 매우안정
처리량 (req/s) : 🔴 매우낮음
🎯 성능 임계값 달성 여부
95% 응답시간 < 1초 : ❌ 미달성 (1927ms)
성공률 > 95% : ✅ 달성 (100.0%)
HTTP 실패율 < 5% : ✅ 달성 (0.0%)
🎯 권장사항
⚠️ 응답시간 최적화 필요 - DB 쿼리 성능 점검
💡 처리량 개선 - 애플리케이션 병목 지점 분석 필요
📈 다음 단계: VU 50개로 스트레스 테스트 진행
🔧 성능 최적화 팁:
- DB 인덱스 최적화
- 응답 데이터 압축 (gzip)
- Redis 캐시 도입
- Connection Pool 튜닝
- batch_size 적용 후
2025-06-23T16:53:55.317+09:00 INFO 61612 --- [techinterview] [nio-9040-exec-2] i.StatisticalLoggingSessionEventListener : Session Metrics {
2110000 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
379958 nanoseconds spent preparing 2 JDBC statements;
37612541 nanoseconds spent executing 2 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
4750 nanoseconds spent executing 1 pre-partial-flushes;
2416 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
=========================================================
Contest List API 상세 성능 테스트 결과
=========================================================
🎯 테스트 대상
URL : <http://localhost:9040/api/v1/tech-interview/1/contests>
테스트 유형 : Contest 목록 조회 API
📊 테스트 실행 개요
총 테스트 기간 : 100.79초 (1.7분)
최대 동시 VU 수 : 30개
평균 동시 VU 수 : 0.0개
총 완료된 반복 : 1388회
반복 처리율 : 13.771/초
🎯 API 요청 성능 분석
총 요청 수 : 1388개
성공한 요청 : 1388개 (100.00%)
실패한 요청 : 0개
API 성공률 : 100.00%
📈 처리량 분석
초당 요청 수 : 13.77 req/s
분당 요청 수 : 826 req/min
VU당 평균 요청 : 46.3 req/VU
⏱️ 애플리케이션 응답 시간
평균 (Average) : 921.37ms
최소 (Min) : 206.00ms
최대 (Max) : 2490.00ms
중앙값 (p50) : 902.00ms
90th percentile : 1597.60ms
95th percentile : 1688.00ms
99th percentile : 0.00ms
🌐 HTTP 네트워크 성능
총 HTTP 요청 수 : 1389개
HTTP 처리율 : 13.78/초
HTTP 실패율 : 0.00%
🕐 HTTP 응답 시간 분포
평균 : 920.73ms
최소 : 206.03ms
최대 : 2489.47ms
중앙값 (p50) : 902.03ms
90th percentile : 1597.62ms
95th percentile : 1688.38ms
99th percentile : 0.00ms
🔧 HTTP 요청 세부 타이밍
연결 설정 시간 : 0.01ms
서버 처리 시간 : 827.16ms
응답 수신 시간 : 93.52ms
요청 차단 시간 : 0.02ms
📊 데이터 전송량
수신된 데이터 : 2963226.68 KB
전송된 데이터 : 230.60 KB
평균 수신 속도 : 29400.36 KB/s
평균 전송 속도 : 2.29 KB/s
요청당 평균 응답크기: 2186127 bytes
💡 성능 등급 평가
응답시간 (평균) : 🟠 보통
응답시간 (95%) : 🟠 보통
안정성 (성공률) : 🟢 매우안정
처리량 (req/s) : 🔴 매우낮음
🎯 성능 임계값 달성 여부
95% 응답시간 < 1초 : ❌ 미달성 (1688ms)
성공률 > 95% : ✅ 달성 (100.0%)
HTTP 실패율 < 5% : ✅ 달성 (0.0%)
🎯 권장사항
⚠️ 응답시간 최적화 필요 - DB 쿼리 성능 점검
💡 처리량 개선 - 애플리케이션 병목 지점 분석 필요
📈 다음 단계: VU 50개로 스트레스 테스트 진행
🔧 성능 최적화 팁:
- DB 인덱스 최적화
- 응답 데이터 압축 (gzip)
- Redis 캐시 도입
- Connection Pool 튜닝
결론
- 16.7% 응답시간 단축
- 14.3% 처리량 증가
- 17.8% 서버 처리시간 개선
하지만 95% 응답시간이 1초를 초과하기 때문에 추가적인 최적화 작업이 필요하다고 생각했습니다.
추가적인 성능 개선을 적용한 부분은 다음 글에 작성해보도록 하겠습니다! 😊