개발/Java|Spring

distinct 로 중복 제거 시 속도 저하 문제

달리초이 2023. 1. 18. 09:36

 

요구사항 : 결과값에서 중복 제거

구현된 기능 중 약 100만 건 가량의 데이터가 조회되는 기능이 있었다. left join 문이지만 단순 조회라서 위 이미지에서 보는 것처럼 시간 성능은 126ms 근처를 오가는 수준. 중복 결과를 제거해야 될 요구사항이 생겨 distinct를 이용해 간단히 해결하려고 했다.

 

하지만,

 

문제 발생

속도 저하라는 더 큰 문제에 직면했다. (0.1초에서 14초로 늘어나다니...😱)

참고로 중복 제거 결과 데이터의 양은 약 31만건.

 

문제 원인

아래 생략. 총 64개 컬럼...😵

 

DB 조회 후 응답 객체로 도메인 객체를 바로 사용하고 있었다. 도메인은 건드릴 수 없는 상황이고, 기존의 도메인 객체는 이미 컬럼이 엄청 많은 상태다. 그래서 인덱스를 태워도 Distinct 사용 시 압도적으로 높은 cost가 발생할 수 밖에 없었다.

 

이 높은 cost가 보이는가. Distinct를 위해 모든 컬럼값의 정렬 작업을 하는 데 시간을 낭비하고 있다.

 

문제 해결

당연히 도메인 객체 대신 필요한 부분만 뽑아내어 DTO를 구성하고 필요한 DB인덱스도 새로 생성 후 응답을 받도록 했다. QueryDSL 을 이용하고 있기에 @QueryProjection 어노테이션을 이용하여 Q객체를 만들어 Projection 처리를 해 주었다.

 

 

그랬더니 해당 부분은 비약적으로 속도가 개선되었다.

 

결론적으로는 응답 객체에 포함되어야 할 내용 중에는 도메인 객체의 연관 관계에서 가져오는 값들이 추가로 더 있었고, JPA로 처리하기 좀 까다로운 부분이라 추가적인 작업이 필요했다. 어쨌든 데이터를 다룰 때 무턱대고 가져오지 말고 목적에 부합하도록 잘 설계할 필요가 있다.

 

 

728x90
반응형