강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

코린코린님의 프로필 이미지
코린코린

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

주문 조회 V3.1: 엔티티를 DTO로 변환 - 페이징과 한계 돌파

BatchSIze 동작과 관련해서 궁금한 점이 있습니다!

작성

·

334

1

안녕하세요. 항상 좋은 강의, 답변 주셔서 감사합니다

BatchSize 동작과 관련해서 궁금한 부분이 있어서 글을 적습니다. 

 

@BatchSize(size = 100)
@GetMapping("/api/v3.1/orders")
public List<OrderDto> ordersV3_page(
@RequestParam(name = "offset", defaultValue = "0") int offset,
@RequestParam(name = "limit", defaultValue = "100") int limit
){
List<Order> orders = orderRepository.findAllWithMemberDelivery(offset, limit);


return orders.stream()
.map(order -> new OrderDto(order))
.collect(Collectors.toList());

}

위 코드에서 BatchSize로 OrderItems와 Item을 불러올 때, where절에 in으로 PK가 나가는 것으로 알고 있습니다.

 

예를 들어

1.Order →  OrderItems 지연 로딩 시, Order PK 값들이 In 절로 들어갑니다.

2. OrderItems → Item 지연 로딩 시, OrderItems PK 값들이 In 절로 들어갑니다. 

 

궁금한 부분은 다음과 같습니다.

1. OrderItems → Item으로 갈 때, OrderItems의 PK를 넘겨서 값을 가져오는데, 이 때 쿼리를 내보내는 시점에 JPA가 어떤 PK를 넘기는 것인지 궁금합니다.

 

위의 코드만 본다면, 영속성 컨텍스트에서 관리하고 있는 모든 PK를 보내는 것이 아닌, stream에서 강제 로딩을 하는 PK 값들만 JPA가 보내는 것으로 이해할 수 있을 것 같습니다.

 

그런데 Stream은 순차적으로 접근하니, 순차적으로 접근하면 접근할 때 마다 쿼리가 나가야하는데 이를 BatchSize를 100으로 설정했기 때문에 Stream으로 활성화(?)된 PK 값들이 한방에 나간다고 이해하고 있습니다

 

이 때, BatchSize를 100으로 설정한다면 Stream을 돌 때 마다 DB에서 불러와야할 PK값이 영속성 컨텍스트 내의 쓰기지연 저장소에 차곡차곡 쌓여있는 것으로 이해를 하면 될까요? 

 

그래서 Stream을 다 돌고 나면 쌓인 PK 값들에 대해 Select + where + in 절로 한번에 join 쿼리를 보내주는 것으로 이해를 하면 될까요? 

 

만약 Stream을 다 돌렸는데 영속성 컨텍스트 내의 쓰기 지연 저장소에 필요한 PK가 200개가 쌓였다고 하면 100개를 먼저 Flush 해주고, 다시 한번 100개를 Flush 해줘서 값을 불러온다고 이해를 하면 될까요? 

 

BatchSize가 실제로 어떻게 동작하는지는 잘 나와있지 않아, 궁금하여 글을 적게 되었습니다.

 

항상 좋은 답변 주셔서 너무 감사합니다.

좋은 하루, 주말 되세요! 

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 안상혁님

다음을 참고해주세요.

https://www.inflearn.com/questions/399849

감사합니다.

코린코린님의 프로필 이미지
코린코린

작성한 질문수

질문하기