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));