🟢

QueryDsl로 쿼리 최적화 (6초 → 0.5초 / 성능 12배 향상)

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

기존 로직

  • 레거시 코드에선 user 리스트를 찾아오고, 리스트를 순회하며 각 user의 call 기록을 찾아온다.
    • Service 레이어 - 레거시
      • Repository 레이어 - 레거시
        • 레포지토리 레이어(다른 예시)
          notion image
    • 레거시 코드에선 데이터 200개 찾아오는 데, 5~6초 가량 소요된다. 🤣
      • notion image
    • 리스트 순회를 통해 사용자마다 데이터베이스 쿼리를 각각 날리기 때문이다.

    변경한 로직 (6초 → 0.5초 / 성능 12배 향상)

    • 쿼리를 한 번에 날리게 해줬다.
    • 일단 sql문부터 짜보았다.
      • 서비스 레이어와 레포지토리 레이어를 리팩토링했다.
        • Service 레이어 - 리팩토링
          • Repository 레이어 - 리팩토링
          • 고작 200개 데이터로 테스트 했는데도 무려 10~12배 정도나 빨라졌다. 물론, 로컬에서 돌린 거라 실행 환경이나 데이터 양에 따라 차이는 있겠지만 말이다.
            • notion image

          변경하다가 발견한 재밌는 쿼리

          아래 두 쿼리는 결과가 다를까? 같을까? 정답을 말하자면, 다르다.
          (1)
          (2)
           
          (1)번 코드는 call이 존재하지 않는 fisUser들은 결과에 뜨지 않고,
          (2)번 코드는 call이 존재하지 않는 fisUser들도 결과에 뜬다.
          (참고로 나는 2번 결과가 필요했다)
           
          왜 그런걸까?
          (1)번 코드는 left join절에서 모든 fisUser를 가진 결과를 만든다. 해당하는 call이 있으면 이를 포함하고 말이다. 하지만, where절에 의해서 date가 일치하는 call이 없는 fisUser들은 모두 결과에서 제외된다.
           
          (2)번 코드는 조건이 조인을 수행할 때 적용되어 다른 결과를 만든다. 즉, fisUser와 call이 조인되고 date가 일치하는지 확인하는데 이때, date가 일치하는 call이 없는 fisUser들은 call 관련 열들이 null로 채워지게 된다. 그 결과 call이 없는 fisUser들도 결과에 포함된다.
           
          On 절의 조건은 데이터 결합을 위한 조건이고, Where 절의 조건은 데이터 필터링을 위한 조건이기 때문인데,
          원리를 더 깊게 알고 싶다면, On 절과 Where 절의 차이에 대해 검색해보자.
           
          QueryDsl 문법 참고
          QueryDsl로 쿼리 최적화 (6초 → 0.5초 / 성능 12배 향상)