"쿼리가 느려요"를 조금 더 구체적인 표현으로 바꾸어보면 문제를 해결할 수 있을 때도 있다
회사 코드를 짜던 중 데이터베이스를 자주 갔다오는 코드가 조금 답답하게 느껴졌다. 아무 생각 없이 옆에 계신 선배분께 "쿼리가 느린것 같아요"라고 말했더니 선배는 이를 조금 더 구체적인 표현으로 바꾸어 주셨다.
때로는 문제를 잘 정의하는 것이 문제 해결의 키가 될 때가 있다. 문제가 된 코드는 8번에 거쳐서 데이터베이스 쿼리를 날리고 있었는데, 이를 앞에서부터 하나씩 요청했기 때문에 네트워크 io를 기다리면서 낭비되는 시간이 많았던 것이었다.
이럴 때는 시간을 측정해보고 해결방법을 적용해 본 뒤에 다시 시간 측정을 해보고 비교해보는 것이 좋다
1st
db query costed 310 ms
db query costed 122 ms
db query costed 87 ms
db query costed 106 ms
db query costed 194 ms
db query costed 411 ms
db query costed 139 ms
db query costed 47 ms
=> 1,416 ms
2nd
db query costed 292 ms
db query costed 184 ms
db query costed 135 ms
db query costed 155 ms
db query costed 223 ms
db query costed 445 ms
db query costed 142 ms
db query costed 42 ms
=> 1,618 ms
3rd
db query costed 389 ms
db query costed 160 ms
db query costed 108 ms
db query costed 161 ms
db query costed 267 ms
db query costed 557 ms
db query costed 2399 ms
db query costed 51 ms
=> 4,092 ms
평균 실행시간 = 2,375 ms
1st
db query costed 138 ms
db query costed 448 ms
db query costed 100 ms
db query costed 165 ms
db query costed 162 ms
db query costed 36 ms
db query costed 142 ms
db query costed 44 ms
=> 1,235 ms
2nd
db query costed 119 ms
db query costed 161 ms
db query costed 117 ms
db query costed 169 ms
db query costed 162 ms
db query costed 45 ms
db query costed 133 ms
db query costed 45 ms
=> 951 ms
3rd
db query costed 105 ms
db query costed 155 ms
db query costed 102 ms
db query costed 182 ms
db query costed 150 ms
db query costed 30 ms
db query costed 138 ms
db query costed 33 ms
=> 895 ms
4th
db query costed 96 ms
db query costed 111 ms
db query costed 105 ms
db query costed 168 ms
db query costed 162 ms
db query costed 55 ms
db query costed 107 ms
db query costed 28 ms
=> 832 ms
5th
db query costed 111 ms
db query costed 138 ms
db query costed 100 ms
db query costed 149 ms
db query costed 122 ms
db query costed 30 ms
db query costed 156 ms
db query costed 64 ms
=> 870 ms
평균 실행 시간 = 956 ms
코틀린의 코루틴으로 최적화를 할까를 고민했는데, async await로 처리하는 것 보다는 completableFuture를 이용하는 것이 조금 더 코드가 보기에 좋다고 생각해서 completableFuture를 사용했다.
val 변수 = 쿼리?: 에러 던짐
lateinit var 변수: 타입
val 변수future = CompletableFuture.supplyAsync {
adUnit = 쿼리?: 에러 던짐
}
...변수& 변수future선언 반복
val combinedFuture = CompletableFuture.allOf(모든 퓨쳐)
combinedFuture.get()
return 결과
1st
db query costed 337 ms
병렬 query costed 2263 ms
=> 2,600 ms
2nd
db query costed 443 ms
병렬 query costed 422 ms
=> 865 ms
3rd
db query costed 365 ms
병렬 query costed 515 ms
=> 880 ms
평균 실행 시간 = 1, 448 ms
1st
db query costed 119 ms
병렬 query costed 199 ms
=> 318 ms
2nd
db query costed 94 ms
병렬 query costed 183 ms
=> 277 ms
3rd
db query costed 101 ms
병렬 query costed 181 ms
=> 282 ms
4th
db query costed 100 ms
병렬 query costed 179 ms
=> 279 ms
5th
db query costed 101 ms
병렬 query costed 172 ms
=> 273 ms
평균 실행 시간 = 285 ms
db쪽에서 cache hit가 발생하지 않았을 경우에는 평균 2,375 ms에서 1,448 ms로 약 40% 성능 향상이 있었고
db쪽에서 cache hit가 발생했을 경우에는 평균 956 ms에서 285 ms로 약 70% 성능 향상이 있었다