1. 성능 최적화의 필요성
2. 쿼리 최적화 방법
1) 스칼라 타입으로 조회
select o.id, o.name, o.price from Order p
2) 읽기전용 쿼리 힌트 사용
@Transactional
public Long updateBoard(UpdateBoardDTO updateBoardDTO) {
Board found = boardRepository.findByIdReadOnly(updateBoardDTO.getId());
Board changed = found.changeBoard(updateBoardDTO);
return changed.getId();
}
@Query(value = "select b from Board b" +
" where b.id = :id")
@QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true"))
Board findByIdReadOnly(@Param("id") Long id);
3) 읽기 전용 트랜잭션 사용
[참고] hibernate가 제공하는 flush mode
- ALWAYS, AUTO(default), COMMIT, MANUAL
4) 트랜잭션 밖에서 읽기
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
[참고] transaction propagation option
📌 [정리] 경우에 따른 읽기전용 데이터의 성능 최적화
- [1] 메모리를 최적화하자
- 스칼라 타입으로 조회
- 하이버네이트가 조회하는 읽기전용 쿼리 힌트 사용
- [2] 플러시 호출을 막자
- 읽기전용 트랜잭션
- 트랜잭션 밖에서 읽기
- 위 두 가지를 동시에 사용하는 것이 가장 효과적
@Transactional(readOnly = true)
public Page<BoardListDTO> getBoardList(String keyword, Pageable pageable) {
//페이징 처리
//일대다인 boardReplyList의 경우 지연로딩+batch size 옵션 사용
Page<Board> board = boardRepository.findAllPaging(keyword, pageable);
Page<BoardListDTO> res = BoardListDTO.toBoardListDTO(board);
return res;
}
@Query(value = "select b from Board b" +
" where ((b.title like concat('%', :keyword, '%')" +
" or b.content like concat('%', :keyword, '%'))" +
" or (:keyword is null or :keyword = ''))" +
" order by b.createdAt desc")
@QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true"))
Page<Board> findAllPaging(@Param("keyword") String keyword, Pageable pageable );