ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 성능 개선을 진행해보자 1편
    스프링 2024. 7. 3. 04:44

     

     

    성능 개선하기

    서론

    현재 bookMark에 100만개의 데이터를 넣어놓았다.
    이에따라 연속 독서기록량을 체크할 때 성능이 매우 좋지 않았다.
    전체 책갈피 조회 쿼리를 다시 점검해보았는데, 약 8s 정도로 시간이 다소 걸리는 것을 확인할 수 있었다.
    시간을 좀 더 개선시켜보는 것이 목표이다.

    쿼리 DSL로의 변경

    전체 책갈피 리스트를 조회하는데 JPA를 이용하여 다음과 같은 메소드를 사용하고있다.

    public Map<LocalDate, List<AllBookMarkResponseDto>> showAllBookMarkList() {
            List<BookMark> list = bookMarkRepository.findAllByOrderByModifiedDateDesc().stream()
                    .map(AllBookMarkResponseDto::from)
                    .toList();
            return list.stream()
                    .collect(Collectors.groupingBy(
                            AllBookMarkResponseDto::getDate,
                            LinkedHashMap::new,
                            Collectors.toList()
                    ));
        }

     

    findAllByOrderByModifiedDateDesc는 JPA를 이용하여 생성한 메소드이다.
    List를 만들고, 스트림을 통해서 정의된 API 형식의 DTO로 매핑한다.
    이를 query dsl을 이용하여 다시 구성하였다.

     

    @Override
        public List<AllBookMarkResponseDto> findAllByOrderByModifiedDateDesc() {
            return queryFactory
                    .select(Projections.fields(AllBookMarkResponseDto.class,
                            bookMark.id.as("id"),
                            bookMark.modifiedDate.as("date")))
                    .from(bookMark)
                    .orderBy(bookMark.modifiedDate.desc())
                    .fetch();
        }

     

    repository계층에서 바로 DTO로 매핑하여 아키텍쳐적으로 레이어 분리를 하여, 서비스 로직에서
    바로 사용이 가능하도록 하였다.

    성능은 2s대 까지 줄일 수 있었다.

     

     

    query dsl을 사용하면 시간을 줄일 수 있는 이유는 다음과 같다.

     

     

    1. 데이터베이스와의 상호작용
    • Querydsl을 사용한 DTO 반환 방식

     

    데이터베이스에서 실행되는 쿼리 자체가 DTO에 필요한 필드만 선택합니다. 즉, SELECT 절에 필요한 필드만 포함되므로, 데이터베이스에서 전송되는 데이터의 양이 감소합니다.
    데이터베이스에서 필요한 필드만 가져오기 때문에 네트워크 대역폭을 절약할 수 있습니다.

     

    • 엔티티 조회 후 스트림을 통한 매핑 방식:

    데이터베이스에서 엔티티 전체를 조회합니다. SELECT * 쿼리가 실행되어 모든 필드가 선택됩니다.
    불필요한 데이터가 전송되므로 네트워크 대역폭과 메모리 사용량이 증가할 수 있습니다.

     

     

    1. 메모리 사용량
    • Querydsl을 사용한 DTO 반환 방식

     

    데이터베이스에서 필요한 필드만 메모리에 로드되므로 메모리 사용량이 적습니다.
    DTO 객체만 생성되므로 불필요한 엔티티 객체가 생성되지 않습니다.

     

    • 엔티티 조회 후 스트림을 통한 매핑 방식

     

    모든 엔티티를 메모리에 로드한 후, 이를 DTO로 변환합니다.
    이 과정에서 엔티티와 DTO 객체가 모두 메모리에 존재하게 됩니다.
    메모리 사용량이 증가할 수 있습니다.

     

     

    1. CPU 사용량
    • Querydsl을 사용한 DTO 반환 방식

     

    DTO 변환 작업이 데이터베이스에서 수행되므로, 애플리케이션 서버의 CPU 사용량이 감소합니다.
    데이터베이스가 변환 작업을 대신 처리하기 때문에 애플리케이션 서버의 부하가 줄어듭니다.

     

    • 엔티티 조회 후 스트림을 통한 매핑 방식

     

    엔티티를 조회한 후, 애플리케이션 서버에서 DTO로 변환하는 추가 작업이 발생합니다.
    스트림을 통해 매핑하는 과정에서 CPU 사용량이 증가할 수 있습니다.

     

     

    728x90

    댓글

Designed by Tistory.