티켓 예매 사이트 - 5
JPA N+1 문제 해결

내 예매 내역을 조회하는 단순한 API에서 콘솔창에 SQL 쿼리가 20개 이상 쏟아지는 현상을 발견했다.
Fetch Join을 사용해 해결했으며, 혹시 몰라 배치 사이즈도 추가했다.
발생한 이후는 단일 테이블만 조회 -> Lazy로 설정되어 있기 때문에 비어있는 객체를 불러옴 ->
JPA가 DB에 필요한 데이터들을 SELECT로 계속 조회
적용한 코드
@Query("select distinct r from Reservation r " +
"join fetch r.schedule s " +
"join fetch s.performance p " +
"left join fetch r.reservationSeats rs " +
"left join fetch rs.seat " +
"where r.member.id = :memberId " +
"order by r.createdAt desc")
수정 전
Hibernate:
select
p1_0.id,
p1_0.category,
p1_0.color,
p1_0.date_text,
p1_0.price,
p1_0.slug,
p1_0.subtitle,
p1_0.symbol,
p1_0.tag,
p1_0.title,
p1_0.venue
from
performances p1_0
where
p1_0.id=?
Hibernate:
select
p1_0.id,
p1_0.category,
p1_0.color,
p1_0.date_text,
p1_0.price,
p1_0.slug,
p1_0.subtitle,
p1_0.symbol,
p1_0.tag,
p1_0.title,
p1_0.venue
from
performances p1_0
where
p1_0.id=? ........수정 후
select
distinct r1_0.id,
r1_0.created_at,
r1_0.hold_token,
r1_0.member_id,
r1_0.order_id,
r1_0.order_name,
r1_0.paid_at,
r1_0.payment_key,
rs1_0.reservation_id,
rs1_0.id,
rs1_0.seat_id,
s2_0.id,
s2_0.hold_expires_at,
s2_0.hold_token,
s2_0.schedule_id,
s2_0.seat_number,
s2_0.status,
s2_0.version,
r1_0.schedule_id,
s1_0.id,
s1_0.performance_id,
p1_0.id,
p1_0.category,
p1_0.color,
p1_0.date_text,
p1_0.price,
p1_0.slug,
p1_0.subtitle,
p1_0.symbol,
p1_0.tag,
p1_0.title,
p1_0.venue,
s1_0.start_time,
r1_0.status,
r1_0.total_amount
from
reservations r1_0
join
performance_schedules s1_0
on s1_0.id=r1_0.schedule_id
join
performances p1_0
on p1_0.id=s1_0.performance_id
left join
reservation_seats rs1_0
on r1_0.id=rs1_0.reservation_id
left join
seats s2_0
on s2_0.id=rs1_0.seat_id
where
r1_0.member_id=?
order by
r1_0.created_at desc
SQL 호출 개수가 줄었기 때문에 DB에 가는 부담이 줄어들었다.
이 프로젝트는 대규모 좌석 처리와 JPA의 SQL 호출의 워크플로우를 배우기 위해서 시작했으므로
일단은 여기서 마무리하려한다. 나중에 다른 대규모 처리를 활용해 보고 싶을 때 이 프로젝트에
붙여서 사용해보도록 하겠다.
댓글 0
댓글을 불러오는 중입니다.