반응형
문제 상황
Board, Column, Card 엔티티가 각각 1:N, 1:N 관계일 때, Board와 관련된 Column, Card를 모두 조회하려고 했다. (단, Column은 Column의 weight 필드를 기준으로 정렬해서 조회하고, Card는 Card의 weight 필드를 기준으로 정렬해서 조회한다.) 이때, 단순히 조회하면 N+1 문제가 발생해서 Board와 연관된 Column N개, Column과 관련된 Card M개를 조회하면서 N*M번 불필요한 쿼리를 수행하게 된다.
생각
- 처음엔 한 번에 column과 card를 fetch join 하려고 했었는데, MultipleBagFetchException: cannot simultaneously fetch multiple bags 예외를 만났다. 이건 여러 bag 컬렉션을 fetch join 으로 가져올 때, Hibernate가 bag 컬렉션을 처리하는 방식과 SQL JOIN 쿼리의 결과 특성상 카테시안 곱이 발생하고, 이것으로 인해 성능 문제가 발생할 수 있기 때문에 발생하는 예외다.
- 그래서 Board-Column을 Fetch join 하고, Column의 id 리스트로 Column-Card를 Fetch join 해서 2개의 쿼리로 조회 최적화를 시도했다.
// Board-Column fetch join
public Optional<Board> findOneWithColumns(Long boardId) {
return Optional.ofNullable(queryFactory.selectFrom(board)
.leftJoin(board.columns, columns).fetchJoin()
.where(board.id.eq(boardId))
.fetchOne());
}
// Column-Card fetch join
@Query("select c from Columns c left join fetch c.cards where c.id in :ids order by c.weight")
List<Columns> findAllByIdIn(List<Long> ids);
반응형
'Trouble shooting' 카테고리의 다른 글
NGrinder Controller Local IP Address 설정 문제 (0) | 2024.02.03 |
---|---|
[Vuex] 새로고침 했을 때 store 초기화 문제 해결 (0) | 2023.10.10 |