jpa2활용(2)

김민지·2022년 12월 15일
0

JPA

목록 보기
25/27

컬렉션 조회 최적화

order을 select하는데 몇번의 쿼리가 나갈까?
order는 member, delivery에서는 일에 대응되고
order은 orderitemlist를 가지고 orderitem은 itemList를 가진다

(order조회개수만큼)
select member
select delivery
(orderitem개수만큼)
select orderitem
(item개수만큼)
selec item

fetch join 해보자

  • 컬렉션 조회에 의해 데이터가 뻥튀기된다
    같은 order가 여러개 조회가 된다
  • 의도했던거랑 다른 결과가 나온다

db의 distinct는 한줄이 다 똑같아야 중복이 제거가된다
db쿼리의 결과에선 중복제거가 안됨
jpa에서는 distincct는 중복을 제거해서 하나의 객체를 버려준다

em.createQuery().setFirstResult(1).setMaxResults(100).. 이런 페이징 조건을
쓸 수 없다
order객체는 2개지만 (일대다조인한순간)디비쿼리로는 데이터가 4개이다
그렇기때문에 애초에 페이징이 안됨.. 디비 조회 결과자체가 두개가 나왔어야함

  • 컬렉션 페치 조인은 페이징이 불가능
  • 컬렉션 페치조인은 1개만 사용가능

일대다 조인을 하면 다 기준으로 row가 여러개 중복해서 생성됨.
하지만 일대다 조인을 하는 이유는 일을 기준으로 데이터를 생성하기 위함임.
그래서 일을 기준으로 페이징 하고싶음
-> 하이버네이트는 모든 DB데이터를 읽어서 메모리에서 페이징을 시도.
모든 DB데이터가 메모리에 올라오는것은 매우 위험한 상황. 장애로 이어질 수 있음

페이징 + 컬렉션엔티티 함께 조회

  1. toOne(단일건)은 페치조인 - fetch join해도 row를 증가시키지않으니 괜찮아
  2. toMany(리스트건)은 지연로딩으로 조회한다
  • 지연로딩 성능최적화를 위해 @BatchSize를 적용한다

application.properties

default_batch_fetch_size:100//최대 100개를땡겨옴

orderitem을 매번 id에 해당하는것을 가져왔는데
(4,11)
디비에있는 userA의 userB의 orderitem을 한번에 가져옴
order를 가져올때 order의 정보를 기억했다가 지연로딩을 하면 관련된것을 한꺼번에조회해옴
인쿼리로 조회해온다

profile
안녕하세요!

0개의 댓글