스프링부트-JPA-활용-8

존스노우·2022년 1월 19일
0

스프링

목록 보기
19/22

# API 개발 고급 - 컬렉션 조회 최적화

1대 N 관계 최적화

데이터가 뻥튀기 되서 조심 스럽다.

V2

프록시 초기화 진행

이 방법도 DTO 하나로 감싸서 보내라는게아니라

안에있는 orderItem 객체가 있어도 안됀다. 그대로 반환하면 안돼고

orderItem도 Dto로 변환해서 반환해야된다.

이런식으로 변환

속에있는거 까지 다 엔티티없이 DTO로

쿼리가 많이나간다..

order 1 -> member 1 -> delivery 1 -> orderItem 1 ->item 2

V3

join 하면 다대 1에서 뻥튀기..

이런식으로..

한개 오더의 2개의 오더 아이템이 있기 때문에..

1:N 경우 하나에 대해서 N개의 결과가 나와버림..

중복 제거 해주자

여기서 문제점은 -> DB distinct는 정말 두줄이 다 같아야 없에주는대..

JPA는 그게아님.. 자체적으로 DISTINCT 같은 ID 값이면 하나를 버린다.

기능 -> 디비에 distinct 엔티티가 중복인경우 중복을 걸러서 담아줌.

결과는 깔끔하게나옴.

페이징이 불가라니..

실제로 페이징 처리가 되지 않는다.

메모리에서 페이징 처리를해서 오류가 난다.

api에서는 중복이 걸러져서 나오지만

db 에서 1:N 조인 하는순간 결과로그가 4개이다.

우리가 원했던 결과가 아니다(2개) 세번째 부터가져와 두번째 부터가져와..

페이징 자체가 불가능하다. (데이터 뻥튀기때문에 데이터를 못맞춤)

왜냐하면 오더 아이템 기준으로 페이징이 되기때문에 (디비입장)

1대 N 경우 페치 조인을쓰면 페이징을 쓰면안됌..

1:N:N 쓰면안됌...

V3

한계 돌파

다대일 페치조인은 데이터 뻥튀기가 되지않기 때문에 (원투원 포함)
한방에 페치 조인 만들어도 됨

@BatchSize 적어둔 갯수만큼 미리 땡겨온다.

페치조인된건 한방에 가져오지만

1.오더아이템 쿼리 1개 -> 아이템 쿼리 2개
2.오더아이템 쿼리 1개 -> 아이템 쿼리 2개 이런식.. Lazy Loading

옵션넣어주자

결과는 잘나오니 생략

In Query가 들어가있네?

정리하면

Order 가져올때 컬렉션 정보를 알고 있어서.
컬렉션과 관련된 얘들을 미리 in 쿼리로 해서 가져온다
아까 선언언 size 100은 인 쿼리 몇개 할꺼야? 뜻이였다.

1 N M - > 1 : 1 : 1 로 만들어 진다.

이런식으로 배치옵션 ..

배치사이즈를 사용하면서 데이터를 가져오는 갯수는 똑같다.

주문 조회 V4

특정화면에 관련된 부분은 따로 분리. (관심사 분리)

정상출력

정리 ->

최초 Order 쿼리 (컬렉션 제외) 1번 날리고 컬렉션 N 번 실행

레파지토리에서 Order 가져오고 -> order 루프 돌면서 orderItem 가져오고
가져온 orderItem 셋 해주고 마지막에 뿌려준다.

findOrderItems ToOne 관계 (데이터중복업승ㅁ)

N+1 문제가 터지니까.. 다시 최적화..

주문 조회 V5 DTO 직접 조회 컬렉션 조회 최적화

쿼리가 2번나가서 최적화됨

Collector.groupingBy 동작원리는 키값에 orderId를 넣어주고 value에 그 값을 넣어준다.
ex) orderId,OrderItemQueryDto

주문 조회 V6 DTO 직접 조회 플랫 데이터 최적화

1대 다 조인으로 중복으로 데이터 출력

장점 -> 쿼리 한번.. paging 불가..

이런식으로 중복제거해서 발라내면되는대 굳이..?

정리

상황에 따라 맞게쓰자 entity로 쓰면 하이버네이트가 자동최적화..

DTO로 하면 복잡해지는거일수도있따

V3=v5 같은 방식..?

profile
어제의 나보다 한걸음 더

0개의 댓글