이번글은 제가 우선순위 업데이트를 구현하는 과정에서 발생한 문제를 해결하는 글입니다.
문제상황
우선순위 업데이트를 할때 update문이 여러번 실행되는것입니다.
우선순위를 바꿀때 하나의 로우에서 우선순위 컬럼이 2로 변경된다면 이에따른 메뉴들의 우선순위가 다같이 변경되어야한다고 생각해서 구현을 한 상황에서 db호출이 여러번 진행되므로 db호출을 할때 connection을 맺고 그리고 쿼리를 실행하는 과정이 반복되기때문에 느려진다고 판단했습니다.
프론트에서 받는데이터
[{id : 1, priority:3}, {id : 2, priority:1}, {id : 1, priority:4}, {id : 1, priority:5}] 프론트에서 저는 화면에 배치된 순서대로 받는다고 가정했습니다.
요구사항
하나의 connection에 쿼리를 여러번 실행해주는 방법이있으면좋겠다.
이에 따라 성능이 더 개선이 됬으면좋겠다.
해결방법
Mybatis의 foreach를 통해 배치처리를 하기때문에 DB connection한번에 여러번 쿼리를 실행수있게되었습니다.
저는 Mysql을 사용했습니다
코드는 아래와 같습니다
데이터는 1000건을 넣었습니다.
서비스계층에서 for문을 통해 update를 호출하는경우는 아래와 같이 681~1266 ms 사이의 값이 나왔습니다.
반면 mapper에서 batch처리를 한경우는 300대의 ms정도나오면 최소로 Time : 237 ms 정도 나왔습니다.
그렇다면 여기서 만약 데이터가 더 많아진다면 batch처리가 훨씬 빠르겠다 생각했습니다.
그런데 여기서 고민이 생겼습니다 MenuGroup의 우선순위를 업데이트하는곳에서 사용되는데도 이렇게 많은 데이터가 들어가는 경우가 있을가? 그렇다면 for문이 빠르지 않을가 하고 저희가 구현하는 서비스를 현실적으로 생각해 개수를 낮춰보았습니다
📘10건의 경우는
batch처리 - Time : 134
for문 - Time : 231
📗5건의 경우
batch처리 - Time : 179
for문 - Time : 149
건수가 낮아질수록은 for문이 더 빨라진다는것을 알았습니다. 그렇다면 배달의 민족앱에서 그룹을 몇개정도 만드는지
조사해봤습니다. 제가 사는 주변 치킨집을 조사한결과 평균적으로 7개이며 떡볶이집은 10개 이상인 곳이 존재하기도했습니다.
그렇다면 업데이트건수가 적은경우로 맞춘 for문으로 만든다면 건수가 많아지면 차이가 확연히 벌어지기때문이며 추가적으로 저희가 추구하는 개발은 대용량 처리이기때문에 데이터 건수가 적더라도 속도 차이가 얼마 나지않는 batch처리를 선택했습니다.
여기서 보다시피 데이터 건수를 많이 추가할수록 batch처리를 이용하는것이 성능에 훨씬 도움이됩니다.
😅업데이트 추가적 문제
업데이트가 일부분만 이루어지는 부분이 존재하는 문제가 생길것이라고 생각됬습니다.
만약 이러한 문제가 발생한다면 정확한 우선순위대로 정렬되지 않는 문제입니다.
bulk업데이트시에는 id가 존재하지않아도 업데이트가 빈곳으로 진행됩니다. 그렇다면 3개만 업데이트 되는경우가 존재하는데 이런경우를 막기위해서 앞부분에서 id가 모두다 존재하는지 파악하였습니다.
mybatis의 bulk업데이트는 좋지만 id존재하지않으면 SqlExcetpion을 보내주지않아서 조금 아쉬운점이있습니다.
그래서 이부분을 보완하기위해 size를 파악하여 업데이트 개수가 맞는지 1차적으로 파악해서 DB connection까지 가지않고 예외를 던져주는것입니다.
해결한 코드는 아래와 같습니다
더안전한 방법은 for문을 하나하나돌리면서 파악하는방법인데 이것은 너무 비효율적이라 생각합니다
꼭 안전성 측면에서는 그렇지만 업데이트가 안되는경우는 서비스에서 완전 큰일날 부분이아니라고 생각했고 성능이 느려져 오히려 서비스에서 문제가 생길것이라고 생각합니다.
'Delivery' 카테고리의 다른 글
레디스를 선택한 이유, 세션클러스터링 (0) | 2022.08.05 |
---|---|
레디스에 대해 알아보자 (0) | 2022.08.05 |
테스트코드의 MockMvc utf-8 성능측정 (0) | 2022.07.19 |
Mybatis ${}, #{} 차이 (0) | 2022.07.17 |
피드백 반영 리펙토링 후기 (0) | 2022.07.16 |