[TIL] 애플리케이션 대신 DB로 기능 리팩토링

서버 코드를 보고 서버의 메모리를 생각할 수 있어야 한다.

// 변경 전
@Transactional(readOnly = true)
fun countLoanedBookV_1(): Int {
    return userLoanHistoryRepository.findAllByStatus(UserLoanStatus.LOANED).size
}

DB에 존재하는 데이터를 모두 가져와서,
애플리케이션이  size를 계산한다.

// 변경 후
@Transactional(readOnly = true)
fun countLoanedBookV_2(): Int {
    return userLoanHistoryRepository.countByStatus(UserLoanStatus.LOANED).toInt()
}

DB로 부터 숫자를 가져와서,
적절히 타입을 변환해준다. (Long -> Int)

두 코드 중 어떤 코드가 더 좋은걸까?

겉보기에 두 기능은 완전히 동일하다.

하지만 내부 동작은 전혀 다르다.

1. 전체 데이터 쿼리 , 메모리 로딩 + size

2. count 쿼리 , 타입변환

100만건 ,1000만건…. 등 부하를 고려한다면,

2번의 방법이 네트워크 부하, 애플리케이션 부하가 덜 든다.

일반적으로, 전체 데이터 쿼리를 메모리 로딩 후

애플리케이션에서 처리하는 것 보단,

DB에서 처리하는게 좋다고 생각한다.

정리

데이터의 양/트래픽/비즈니스 요구사항이나

대용량 통계 처리 배치로 비동기적 업데이트하거나

이벤트 발행과 메시징 큐를 이용한 느슨한 결합 등

시스템 아키텍처로 처리할 수도 있어서 상황에 따라서 다르지만,

개발자라면 서버의 코드를 보고 쿼리의 동작 방식이나

메모리의 구조를 알 수 있어야 하고,

적절한 방법을 생각할 줄 알아야 한다!