요구사항 : 결과값에서 중복 제거
구현된 기능 중 약 100만 건 가량의 데이터가 조회되는 기능이 있었다. left join 문이지만 단순 조회라서 위 이미지에서 보는 것처럼 시간 성능은 126ms 근처를 오가는 수준. 중복 결과를 제거해야 될 요구사항이 생겨 distinct를 이용해 간단히 해결하려고 했다.
하지만,
문제 발생
속도 저하라는 더 큰 문제에 직면했다. (0.1초에서 14초로 늘어나다니...😱)
참고로 중복 제거 결과 데이터의 양은 약 31만건.
문제 원인
DB 조회 후 응답 객체로 도메인 객체를 바로 사용하고 있었다. 도메인은 건드릴 수 없는 상황이고, 기존의 도메인 객체는 이미 컬럼이 엄청 많은 상태다. 그래서 인덱스를 태워도 Distinct 사용 시 압도적으로 높은 cost가 발생할 수 밖에 없었다.
이 높은 cost가 보이는가. Distinct를 위해 모든 컬럼값의 정렬 작업을 하는 데 시간을 낭비하고 있다.
문제 해결
당연히 도메인 객체 대신 필요한 부분만 뽑아내어 DTO를 구성하고 필요한 DB인덱스도 새로 생성 후 응답을 받도록 했다. QueryDSL 을 이용하고 있기에 @QueryProjection 어노테이션을 이용하여 Q객체를 만들어 Projection 처리를 해 주었다.
그랬더니 해당 부분은 비약적으로 속도가 개선되었다.
결론적으로는 응답 객체에 포함되어야 할 내용 중에는 도메인 객체의 연관 관계에서 가져오는 값들이 추가로 더 있었고, JPA로 처리하기 좀 까다로운 부분이라 추가적인 작업이 필요했다. 어쨌든 데이터를 다룰 때 무턱대고 가져오지 말고 목적에 부합하도록 잘 설계할 필요가 있다.
'개발 > Java|Spring' 카테고리의 다른 글
Spring Security Custom Fiilter 적용(UsernamePasswordAuthenticationFilter를 활용해 모든 권한을 가진 tester 계정 만들기) (0) | 2023.02.07 |
---|---|
인텔리제이(IntelliJ) 코드 실시간 반영(서버 자동 재시작) (0) | 2023.01.19 |
스프링 의존성주입 생성자주입(@RequiredArgsconstructor 쓰는 이유) (0) | 2023.01.18 |
Spring Security Authentication(인증) (0) | 2023.01.18 |
Spring Security 개념, 아키텍처, 필터 순서, 예제 (0) | 2023.01.17 |