🟢

API 성능 테스트, 12초→0.57초로 향상(with batch fetching)

작성일자
Oct 24, 2023
태그
SPRING
프로젝트
FIS
책 종류

API 성능 테스트 (with fetch join)

(1) 예상

  • 1번 방식) 기존 api에서 center 정보 가져올 때
    • 기존 쓰던 대로 api 쓰면 됨(서버 통신 그대로)
    • 센터 정보 찾는 쿼리 날릴 때 최적화 쉬움
      • jpa에서 제공하는 fetch join+batch 기능을 사용해서 쿼리 수가 n/배치사이즈으로 줄어들고 중복데이터는 안가져와서 최적화 쉬움
        • select * from center where id in (1,2,3)
    • 같은 트랜잭션 내에서 조회해오기에 데이터 일관성을 보장할 수 있음
  • 2번 방식) 새로운 api에서 center 정보 추가로 가져올 때
    • api를 한 번 더 날려야 함(서버 통신 + 1)
    • 센터 정보 찾는 쿼리 날릴 때 최적화 어려움
      • id 100개면 쿼리도 100번 날려야 함 → n
        • select * from center where id=1
        • select * from center where id=2
      • 설령 in 절 사용하더라도 배치 처리 따로 또 해주지 않으면 최적화 힘듦
        • select * from center where id in (1,2,1) → 중복은 in이 알아서 처리해준다.
        • 배치 처리만 안된다.

(2) 결과

  • 아래 코드를 컨트롤러 단에 넣어주어 측정했다. 아 근데 포스트맨 사용 중이면 포스트맨에도 실행 시간 뜬다.
    • 2번 방식 테스트 전 짧막한 수정)
      • 어….. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 70개 가져오는데 12초
      • 문제의 레거시 쿼리…..
        • findById 사용하게 바꿔줬다. fetchAll은 필요가 없으니,, 아마 센터 상세 조회 api가 저 쿼리 사용하는 함수를 같이 쓰고 있어서 문제일 텐데 일단 테스트용이니 잠깐 바꿔줘자.
          • 3.8초로 줄었지만 그래도 여전히 오래 걸린다.
          • 조금 더 최적화해서 in절 사용하게 해보자..
          • 1번 방식) fetch join
            • 0.734초
          • 2번 방식) 일반 select
            • 70개 가져오는 데 0.3초 + 4.1초
            • in절 사용할 땐 70개 가져오는 데 0.3초 + 0.27초 = 0.57초
          참고

          (3) 후속 테스트

          • 1번 방식과 2번 방식의 차이가 애매한데, 좀 더 많은 양의 데이터로 좀 더 정교하게 비교해보기로 했다.
          • 일단 가져오는 데이터 필드를 똑같게 만들어줬고 데이터 양을 둘다 똑같이 902개로 늘렸다.
            • 순서 보장
              • MySQL 무순서성 : 순서 보장 안되므로 정렬 넣어줬다
                • 추가로.. hashMap을 쓰고 있어서 더욱 순서 보장이 안되었다. LinkedHashMap으로 바꿔줬다. 사실 이것만 해줘도 순서 보장 된다.
            • 1번 방식) fetch join (select in)
              • 0.688초 ~ 0.9xxx초
              • 기존 쿼리
            • 2번 방식) select in
              • 0.554초 + 0.322초 = 0.8xxx초
              • 기존 쿼리
                select in 쿼리
            • 여전히 비슷하다. 더이상 데이터 늘리려면 query string 자리가 부족해지기에 여기까지만 테스트하고 정리했다.

            (4) 결론

            • 1번 방식을 사용하기로 했다. 직적 쿼리 짤 필요 없이 같은 성능으로 간단히 최적화해주기 때문이다.

            N+1문제와 batch

            • 정의) 연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오는 현상
            • 특징) batch를 사용해 fetch join을 하면 in 절로 select 해와 N+1 문제를 해결할 수 있다.