SELECT문으로 데이터를 가져올 때 랜덤으로 순서가 바뀌어야하는 요구사항이 존재하였습니다.
해당 기능을 구현하기 위해서 2가지 방안을 생각했었습니다.
1. DBMS에서 ORDER BY RANDOM()를 통해 랜덤하게 가져오도록 개발
2. SELECT 문으로 데이터를 가져온 후 웹 애플리케이션단에서 랜덤하게 순서변경 로직 개발
1번째 방안으로 개발을 진행한 후 성능테스트 이후 성능저하가 심할경우 2번째 방안으로 개발하도록 계획을 수립하였습니다.
쿼리문
<select id="getByToken" parameterType="java.lang.String" resultMap="ReceiverInfo">
select receiver_key, user_id, amount, is_received from tb_receiver
where token = #{value}
</select>
<select id="getByTokenRandom" parameterType="java.lang.String" resultMap="ReceiverInfo">
select receiver_key, user_id, amount, is_received from tb_receiver
where token = #{value} order by RANDOM()
</select>
테스트 코드
@Test
public void 랜덤으로_정렬된_데이터_가져오기() {
receiverDao.getByTokenRandom("Asq");
}
@Test
public void 정렬하지_않는_데이터_가져오기() {
receiverDao.getByToken("Asq");
}
테스트는 다음과 같이 진행하였습니다.
10회 이상 진행 후 수행되는 시간의 평균값을 구함
테스트 결과(테스트 데이터 건수 6,000건)
랜덤으로 정렬된 데이터를 가져올 때가 정렬되지 않은 데이터를 가져올때 보다 약 5배가량 빠른것을 확인할 수 있었습니다. 예상과 다르게 왜 이런결과가 나올걸까요??
혹시 데이터 건수가 많을 경우 다른 결과가 나올 수 있을 것 같아 더 많은 데이터 건수로 테스트를 진행해보았습니다.
테스트 결과(테스트 데이터 건수 30,000건)
테스트 데이터가 증가됨에 따라 랜덤으로 가져올 때 수행시간이 더 걸렸음을 확인할 수 있었습니다. 테스트 데이터 건수를 더 증가시켜 확인해보았습니다.
테스트 결과(테스트 데이터 건수 100,000건)
테스트 결론 : 테스트 데이터 건수가 증가될 수록 성능저하가 발생합니다.
그렇다면 왜 랜덤하게 가져올 때 성능저하가 발생하는 것일까요??
h2 데이터베이스에서는 쿼리에 대한 실행계획 확인하기 어려워 maria db에서 실행계획을 확인하여 진행하였습니다.
실행계획 쿼리
EXPLAIN SELECT * FROM tb_receiver ORDER BY RAND()
실행계획을 살펴봤을 때 extra를 보면 Using temporary; Using filesort;로 임시테이블을 사용한다고 나타나있습니다.
그렇다면 임시테이블이 어디에 생성되었는지 확인해볼필요가 있습니다.
서버상태 변수 확인
SHOW SESSION STATUS LIKE 'Created_tmp%';
Created_tmp_disk_tables : 21
디스크에 임시테이블이 생성된 것을 확인할 수 있었습니다. 디스크에 임시테이블 or 임시파일은 데이터베이스의 성능저하를 줄 수 있다고 합니다. 랜덤하게 데이터를 가져올 때 디스크에 임시테이블을 생성하기 때문에 데이터베이스의 성능이 저하됨을 알 수 있었습니다.
확정성과 성능을 고려한 결과, 1번째 방안보다는 2번째 방안으로 개발을 진행하는 것이 좋아보입니다.
참조
'Spring' 카테고리의 다른 글
Spring log4j 라이브러리란? (0) | 2021.03.25 |
---|---|
Springframework version 마이그레이션하는 방법 (0) | 2021.03.25 |
Mybatis에서 대량의 데이터를 넣을 때 bulk insert를 사용하자 (0) | 2020.12.05 |
멀티 스레드 환경에서 동일 데이터에 대해서 업데이트 시 고려해야 할 사항 (0) | 2020.12.05 |
@Service, @Controller, @Repository 과 @Component의 차이는? (0) | 2020.12.03 |