들어가기 전..
인턴십에서 통계 관련 작업을 진행하며 DB와 Application 코드 중 어디에서 로직을 처리할지 고민해야 하는 상황이 있었습니다. 특히, 주차에 맞는 날짜를 반환하는 로직을 작성할 때 선택지가 다음과 같았습니다.
1. DB에서 처리:
WEEK() 함수로 주차별로 그룹화한 후, 적절히 날짜를 반환하는 쿼리를 작성한다.
2. Application 코드에서 처리:
- 간단한 SELECT 문으로 날짜 데이터를 조회한 뒤, Java의
LocalDateTime 을 활용해 처리한다. - 예:
date.with(java.time.DayOfWeek.MONDAY).toLocalDate().atStartOfDay()
이 간단한 로직을 작성하는 과정이 작은 고민의 시작이었지만, 결과적으로 “DB와 Application의 역할과 범위를 어떻게 나눌 것인가” 라는 생각까지 나아갔습니다.
이번 글에서는 로직 처리의 적절한 위치를 결정하기 위해 고민했던 과정과 선택의 기준을 기록해보려 합니다.
고민의 시작
처음 스스로 고민했을 때는 DB에 복잡한 로직이 몰려있는 경우 몇 가지 정도의 문제가 있을 것이라는 생각이 들었습니다.
그중에서 가장 큰 문제점이라고 생각했던 부분은 트래픽이 몰릴 경우, 확장되는 시점에 대한 부분이었습니다.
트래픽이 몰리면 수평/수직으로 서버를 확장해야하는데 DB보다는 Application 서버가 쉽게 확장 가능하며, 부하 분산이 상대적으로 저렴하다는 생각이 들었습니다.
DB의 경우 스케일아웃을 위해서는 Replication(복제) 지연 문제, 트래픽 불균형, Sharding의 어려움 등이 존재하고, 만약 성능을 높인다면 높은 비용이 문제가 될 가능성이 있다고 생각했습니다.
따라서 트래픽 증가나 장기적 유지보수를 감안할 때, DB에 과도한 로직을 몰아넣기보다는 되도록 애플리케이션 측에서 처리하는 편이 확장성과 비용 측면에서 유리하지 않을까? 라는 것이 저의 생각이었습니다.
위의 고민과 더불어 “DB와 Application의 역할과 범위를 어떻게 나눌 것인가” 라는 생각을 좀더 다양한 시각에서 알아보기 위해 여러 레퍼런스를 참고해봤습니다.



이러한 고민에 대한 해답을 찾아보면서 이해한 바로는 "반드시 Application에서 처리해야 한다”는 일반화된 결론이라기 보단 “로직 복잡도, 데이터 양, 확장성, 네트워크, 편의성를 종합하여 결정해야한다” 정도라고 생각했습니다.
즉, 언제나 등장하는 트레이드 오프의 범위였습니다.
그렇다면 정말 어떤 범위까지 DB에서, Application 코드에서 관리하는 것이 좋을까요? 위에서 참고했는 글을 정리하면서 제 생각을 더해 정리해보겠습니다.
DB와 Application의 역할과 범위를 어떻게 나눌 것인가
먼저 핵심을 말하자면, 데이터를 불러오는 시점에서부터 “데이터 양을 가능한 한 줄여서 네트워크로 전송”하고, “각자의 강점을 최대한 살리는 방법” 을 적용하는 것이었습니다.
DB에서 처리하는 것이 좋은 경우
1. 집계 연산(AVG, SUM, COUNT, GROUP BY 등)
- DB가 원본 데이터에 직접 접근해 빠르게 계산할 수 있습니다.
- 데이터를 애플리케이션에 전부 가져와 처리하면 전송량과 처리 시간이 급증합니다.
- 예: 유저 1억 명의 매출 합계를 구한다면, DB에서 SUM을 구해 결과만 전달하는 편이 훨씬 빠릅니다.
2. 대규모 데이터 필터링(WHERE, JOIN 등을 통한 축소)
- 쿼리로 “필요한 데이터만” 가져오면, 네트워크 전송량을 크게 줄일 수 있습니다.
- JOIN 역시, 한 번의 쿼리로 원하는 데이터를 묶어서 가져오면, 애플리케이션과 DB 간의 왕복 호출이 줄어듭니다.
3. 데이터 자체가 거대한 경우(대규모 테이블)
- “금 세공” 은유처럼, 원석(대량 데이터)을 멀리 옮기지 말고, DB 내부에서 필요한 형태로 가공해 최소한의 결과만 전송하는 것이 효율적입니다.
4. SQL이 잘하는 Set-based 연산
- 루프(커서), 즉 한 행씩 반복 처리하는 것보다 집합 연산이 더 빠른”것이 일반적인 RDBMS의 장점입니다.
- PostgreSQL 등은 정렬·집계·형변환을 매우 효율적으로 처리하기도 합니다.
Application(애플리케이션)에서 처리하는 것이 좋은 경우
1. 복잡한 비즈니스 로직 / Procedure 로직
- DB의 Stored Procedure(DB 로직 실행 프로그램 코드)는 이식성이나 유지보수 측면에서 불편한 경우가 많습니다.
- “조건 분기, 복잡한 계산, 예외 처리” 등은 일반 프로그래밍 언어(Java, Python 등)로 구현하는 것이 훨씬 편리합니다.
2. DB 스케일 업(Scale-up)에 한계가 있을 때
- DB 성능 확보는 비용이 크게 들고, 이중화·클러스터링에도 제약이 많습니다.
- Application 레벨에서 로직을 처리하면 서버 수평 확장(Scale-out)이 용이하므로 비용을 절감할 수 있습니다.
3. DB 독립성(DBMS 종속성 회피)
WEEK() 함수,DATE_TRUNC() 등 DB 고유 함수를 남용하면 DB 교체 시 로직을 대거 수정해야 합니다.- 반면, 애플리케이션에서
LocalDateTime 같은 라이브러리를 사용하면 DB 교체나 버전 변경의 영향이 적습니다.
4. 데이터가 소규모일 때
- 한 페이지 정도의 데이터만 처리하거나, 캐싱 가능한 규모라면 애플리케이션에서도 간단히 처리할 수 있습니다.
- DB에서 집계하지 않아도 부담이 크지 않은 경우에는 코드 유연성이 더 중요합니다.
결국 “It Depends”
Trade-off 와 마찬가지로 상황에 따라 다르다는 당연한(?) 결과를 도출했지만, 그 상황을 이해하고 적용해보는 것은 다른 문제라고 생각합니다. 이번 기회를 통해 무작정 DB, 무작정 Application 코드에서 로직을 구현하는 것이 아닌 DB와 Application에서 각각 최적의 성능을 내고, 유지보수에 용이할 수 있도록 코드를 작성하는 것이 중요하다는 것을 알게되었습니다.
정리해보자면 4가지의 판단 기준을 가질 수 있습니다.
1. 데이터 규모
- 데이터가 방대하면 DB에서 집계·필터링 후 결과를 가져오는 것이 유리합니다.
- 소규모면 애플리케이션에서 처리해도 문제 없습니다.
2. 연산 복잡도
- 복잡한 절차적 로직은 애플리케이션이 낫고, 집합 기반 간단 연산은 DB가 낫습니다.
3. 개발/유지보수 편의성
- DB Stored Procedure나 DB 종속 함수를 과도하게 쓰면 추적과 테스트가 어렵습니다.
- 코드 관리가 필요하다면 애플리케이션 쪽에 로직을 두는 편이 좋습니다.
4. 네트워크 비용 vs. DB 부하
- DB에서 전부 처리하면 CPU/메모리 부담이 DB에 쏠리지만, 전송량이 줄어듭니다.
- 애플리케이션에서 처리하면 DB 부담은 줄지만, 대량 데이터를 네트워크로 가져와야 합니다.
Reference
- https://marobiana.tistory.com/35
- https://jojoldu.tistory.com/520
- https://www.inflearn.com/community/questions/812141/db에서-join-vs-애플리케이션에서-조합?srsltid=AfmBOoo65wxj9nFAhhnY5QEBY5aw8yG5VSZ5gDRy1bPg2SE1qXyX1EQ2
- https://stackoverflow.com/questions/7510092/what-are-the-pros-and-cons-of-performing-calculations-in-sql-vs-in-your-applica
- https://www.inflearn.com/community/questions/75443/db에-날리는-쿼리는-최대한-간단하게-하라는-의미?srsltid=AfmBOorkviTLO6OorsWpcvXMzv5X5ErhlKgobbuofSy-eSqAJYBayNLT
- https://velog.io/@12onetwo12/DB-Replication-복제-지연-해결
'개발 일지 > 나눔비타민 (인턴)' 카테고리의 다른 글
JPA 없이 통계 시스템 구축하기: QueryDSL + Flyway로 데이터 접근하기 (2) | 2025.02.28 |
---|