쿼리
1. Spring Security 필터 ( 1 )
페이징 ( 페이징 데이터 조회 + 카운트 조회 = 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 )
private User getUserById(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(()-> new IllegalArgumentException("회원을 찾을 수 없습니다."));
return user;
}
초록 - 필터
분홍 - 삭제할 유저와 연관관계인 테이블들 조회
-> n+1 문제
-> 여러 시도를 했으나 실패
global batch 사이즈, jpql hint, 개별적으로 batchsize 전부 안됨....
파랑 - 삭제후 화면에 뛰워줄 페이징 쿼리
너무 많은 시간이 지나서 스킵
로그인 필터 ( 1 ) 초록
BookDonationEventService - getDonationEventV3(eventPageRequest) ( 책 이벤트 / 페이징 + count = 2 ) 주황
BookDonationEventService - findBooksNoStatusByDonationId ( 이벤트에 대한 책 / 페이징 + count = 2 * 이벤트 개수 3 ) 빨강
-> 2 ( 이벤트 1번만 ) , 3 ( 페이징 되는 이벤트가 n개면 n번 해당 이벤트에 대한 책들 페이징 )
=> N + 1 오류는 발생하지 않는다
아래 코드에서 bookId만큰 쿼리가 나간다.
이를 해결할려면 findAllById를 사용하면 한번의 쿼리로 해결이 가능하다.
아래처럼 여러번 나가던 쿼리를 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 ( N )
전부 동일
BookDonationEvent bookDonationEvent = bookDonationEventRepository.findFetchJoinById(donationId)
Page<Book> books = bookRepository.findBooksByDonationId(donationId,BookStatusEnum.DONATION,pageRequest);
=> 쿼리 2번 나는 것을 해결하기 위해 FetchJoin
bookDonationEvent에서 book까지 한꺼번에 조회하면 books에서 추가 쿼리가 안나간다.