프로젝트 23/10/23 작업 일지

song yuheon·2023년 10월 24일
0

Project

목록 보기
10/31

테스트 코드 및 코드 포매팅

N+1 문제 발생 점검 작업

관리자 - 유저 관리 페이지 점검 ( 단순 방문 )

쿼리
1. Spring Security 필터 ( 1 )

  1. 페이징 ( 페이징 데이터 조회 + 카운트 조회 = 2 )

  2. Spring Security 필터 ( 2 )

    왜 쿼리가 2번 나가는 걸까?

멘토님께 질문 할 내용으로 킵해두자

실행 코드 위치
package com.example.team258.common.controller.mixedController.admin;

    public String adminViewV2(@RequestParam(defaultValue = "0") int page, Model model, @RequestParam(defaultValue = "") String userName
            ,@RequestParam(defaultValue = "") String userRole, @RequestParam(defaultValue = "5") int pageSize ) {

        Page<User> users = userService.findUsersByUsernameAndRoleV1(userName, userRole, PageRequest.of(page, pageSize));

        List<UserResponseDto> userResponseDtos = users.stream().map(UserResponseDto::new).collect(Collectors.toList());

        model.addAttribute("currentPage", page);  // 현재 페이지 번호 추가
        model.addAttribute("totalPages", users.getTotalPages());
        model.addAttribute("users", userResponseDtos);

        return "adminV2";
    }

쿼리 발생 코드 위치
package com.example.team258.common.security;
(loadUserByUsername)

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("Not Found " + username));

        return new UserDetailsImpl(user);
    }
}

관리자 - 유저 관리 페이지 유저 검색 ( 유저 이름으로 )

검색 내용이 다수
1. 필터 ( 1 )
2. 유저 페이징 ( 2 )
3. 필터 ( 2 )

검색 내용이 하나
1. 필터 ( 1 )
2. 유저 페이징 ( 1 ( 카운트 조회 제외 )
3. 필터 ( 2 )

관리자 - 유저 삭제 시

  1. 로그인 필터 ( 1 )
  2. API ( AdminUsersService - 삭제할 유저 존재하는지 찾는 쿼리 )
  • User user = getUserById(userId);
            private User getUserById(Long userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(()-> new IllegalArgumentException("회원을 찾을 수 없습니다."));
        return user;
    }
  1. API ( AdminUsersService - 삭제 쿼리 )
  • userRepository.delete(user);

초록 - 필터

분홍 - 삭제할 유저와 연관관계인 테이블들 조회
-> n+1 문제
-> 여러 시도를 했으나 실패
global batch 사이즈, jpql hint, 개별적으로 batchsize 전부 안됨....

파랑 - 삭제후 화면에 뛰워줄 페이징 쿼리

너무 많은 시간이 지나서 스킵

관리자 - 책 나눔 이벤트 관리 페이지

관리자 - 책 나눔 이벤트 관리 페이지 로드시

  1. 로그인 필터 ( 1 ) 초록

  2. BookDonationEventService - getDonationEventV3(eventPageRequest) ( 책 이벤트 / 페이징 + count = 2 ) 주황

  3. BookDonationEventService - findBooksNoStatusByDonationId ( 이벤트에 대한 책 / 페이징 + count = 2 * 이벤트 개수 3 ) 빨강

-> 2 ( 이벤트 1번만 ) , 3 ( 페이징 되는 이벤트가 n개면 n번 해당 이벤트에 대한 책들 페이징 )

  1. 로그인 필터 ( 2 ) 초록

=> N + 1 오류는 발생하지 않는다

관리자 이벤트에 책 추가 페이지 로드

  1. 로그인 필터 ( 1 )
  2. 책 페이징 ( 2 )
  3. 로그인 필터 ( 2 )

이벤트 설정 페이지 ( Book Setting Event )

아래 코드에서 bookId만큰 쿼리가 나간다.
이를 해결할려면 findAllById를 사용하면 한번의 쿼리로 해결이 가능하다.

아래처럼 여러번 나가던 쿼리를 1개로 바뀌었다.

  1. 로그인 필터 ( 1 )
  2. 이벤트 페이지 조회 ID ( 1 )
  3. 이벤트에 설정할 도서들을 한꺼번에 조회 ( 1 )
  4. 이벤트 설정한 도서들 상태를 update ( N )

이벤트 업데이트 ( Update Event )

  1. 로그인 필터 ( 1 )
  2. 이벤트 조회 ID ( 1 )
  3. 이벤트 수정 ( 1 )

이벤트 삭제 ( Delete Event )

  1. 로그인 필터 ( 1 )
  2. 이벤트 조회 ID ( 1 )
  3. 이벤트에 대한 책들 조회 ( 1 )
  4. 이벤트에 대한 나눔 신청들 조회 및 나눔 신청에 대한 책 조회 ( N )
  5. Update & delete ( 나눔 신청들 삭제 및 책 상태 POSSIBLE(대출 가능 )로 상태 변경 = N )

=>

  1. 쿼리 최적화
    @Query("select bde from book_donation_event bde " +
            "join fetch bde.bookApplyDonations bad " +
            "join fetch bad.book b " +
            "where bde.donationId = :donationId")
    Optional<BookDonationEvent> findFetchJoinById(@Param("donationId") Long donationId);

  1. 로그인 필터 ( 1 )
  2. 이벤트 조회 ID FETCH ( 1 )
  3. 이벤트에 대한 책들 조회 ( 1 )
  4. Update & delete ( 나눔 신청들 삭제 및 책 상태 POSSIBLE(대출 가능 )로 상태 변경 = N )

이벤트 종료

  1. 로그인 필터 ( 1 )
  2. 이벤트 조회 ID ( 1 )
  3. 이벤트에 대한 책 나눔신청들 조회 ( 1 )
  4. 책 나눔 신청들에 대한 책들 조회 ( N )
  5. Update & delete ( N )


1. 로그인 필터 ( 1 )
2. 이벤트 조회 ID FETCH ( 1 )
3. 이벤트에 대한 책 나눔신청들 조회 ( 1 )
4. Update & delete ( N )

이벤트 나눔 목록 페이지

이벤트 나눔 페이지 로딩

  1. 로그인 필터 ( 1 )
  2. 이벤트 조회 페이징 ( 2 )
  3. 로그인 필터 ( 1 )

이벤트 나눔 페이지 검색

전부 동일

이벤트 나눔 신청 페이지

이벤트 나눔 신청 페이지 로딩

BookDonationEvent bookDonationEvent = bookDonationEventRepository.findFetchJoinById(donationId)

Page<Book> books = bookRepository.findBooksByDonationId(donationId,BookStatusEnum.DONATION,pageRequest);

=> 쿼리 2번 나는 것을 해결하기 위해 FetchJoin
bookDonationEvent에서 book까지 한꺼번에 조회하면 books에서 추가 쿼리가 안나간다.

이벤트 나눔 신청 페이지 신청

  1. 로그인 필터 ( 1 )
  2. 책 검색 ID ( 1 )
  3. 책 이벤트 ID ( 1 )
  4. 사용자 ID ( 1 )
  5. 책 나눔 신청 생성 및 영속성 컨텍스트로 저장 ( 1 )
  6. bookApplyDonation 책 조회 ( 1 )
  7. user bookApplydonation 조회 ( 1 )
  8. bookDonationEvent의 bookApplyDonation 조회 ( 1 )
  9. 커밋 하면서 영속성 변경감지 -> 전부 업데이트 ( 1 )
  10. 로그인 필터 ( 1 )
profile
backend_Devloper

0개의 댓글