TIL
N+1문제
류정근
2024. 7. 15. 21:49
트러블 슈팅
문제 사항
- 반복문안에 레포지토리(cardAdapter)가 있어서 쿼리문이 비효율적으로 많이 나가는 문제발생
for (Card card : cards) {
// assigneeId가 있는 카드의 경우
if (Objects.nonNull(card.getAssigneeId())) {
BoardUser boardUser = boardUserAdapter.getBoardByUserById(card.getAssigneeId());
cardGetAllResponseDtoList.add(CardGetAllResponseDto.of(card, card.getColumns(), boardUser.getUser().getNickName()));
} else {
// assigneeId가 없는 카드의 경우
cardGetAllResponseDtoList.add(CardGetAllResponseDto.of(card, card.getColumns(), null));
}
}
문제 사항
해결방법
--Map과 where in 을 사용하여 N+1 문제를 해결
//assigneeId 리스트 뽑아오기 및 assigneeId로 BoardUser 리스트 가져오기
List<Long> assigneeIds = cards.stream().filter(c -> c.getAssigneeId() != null)
.map(Card::getAssigneeId).toList();
List<BoardUser> boardUsers = boardUserAdapter.getBoardUsersByIds(assigneeIds);
Map<Long, BoardUser> boardUserMap = boardUsers.stream()
.collect(Collectors.toMap(bu -> bu.getUser().getId(),
bu -> bu));
for (Card card : cards) {
Long assigneeId = card.getAssigneeId();
String nickName = null;
if (boardUserMap.containsKey(assigneeId) && assigneeId != null) {
nickName = boardUserMap.get(assigneeId).getUser().getNickName();
}
cardGetAllResponseDtoList.add(CardGetAllResponseDto.of(card, card.getColumns(), nickName));