이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- OLTP와 OLAP은 같은 DB 기술처럼 보여도 왜 운영 목적이 다른가?
- 운영 DB에서 분석 쿼리를 직접 돌릴 때 어떤 장애와 품질 문제가 생기는가?
- Java/Spring 서비스는 OLTP 정합성과 OLAP 지연 허용치를 어떻게 분리해야 하는가?
- 분석용 적재가 실패했을 때 API 장애와 어떻게 구분하는가?
개요
OLTP는 사용자 요청의 현재 상태를 안전하게 바꾸는 시스템이다.
OLAP은 많은 데이터를 읽어 패턴과 지표를 계산하는 시스템이다.
두 시스템은 모두 SQL을 사용할 수 있지만 성격이 다르다.
OLTP는 짧은 transaction, 빠른 point lookup, 제약 조건, 동시성 제어가 중요하다.
OLAP은 대량 scan, join, aggregate, 지연 허용치, 재계산 가능성이 중요하다.
원리
백엔드 개발자는 운영 DB가 분석 쿼리를 못 한다고 생각하면 안 된다.
운영 DB도 집계 쿼리를 실행할 수 있다.
문제는 그 쿼리가 사용자 요청과 같은 connection, CPU, lock, buffer cache를 경쟁한다는 점이다.
분석 요구가 커지면 운영 DB에서 직접 계산하는 방식은 성능 문제뿐 아니라 지표 정의 문제도 만든다.
비교
| 구분 | OLTP | OLAP |
|---|---|---|
| 목적 | 현재 업무 상태 변경 | 과거와 현재 데이터 분석 |
| 요청 | 짧고 빈번함 | 길고 무거움 |
| 예시 | 주문 생성, 결제 승인 | 일별 매출, 코호트 분석 |
| 데이터 모델 | 정규화된 운영 table | fact, dimension, mart |
| 정합성 | transaction 즉시성 | freshness와 재계산 |
| 장애 영향 | 사용자 API 장애 | 리포트 지연, 의사결정 지연 |
이 차이 때문에 OLTP 장애 대응과 OLAP 장애 대응은 언어가 달라야 한다.
운영 DB 직접 집계 예시
SELECT DATE(created_at) AS order_date,
SUM(paid_amount) AS paid_amount
FROM orders
WHERE created_at >= now() - interval '30 days'
AND status = 'PAID'
GROUP BY DATE(created_at)
ORDER BY order_date;개발 중에는 이 쿼리로 충분해 보일 수 있다.
하지만 주문 table이 커지고 API 요청이 늘면 이 쿼리는 운영 DB의 읽기 자원을 크게 사용한다.
또한 환불, 취소, 테스트 주문 제외 기준이 dashboard마다 달라지기 쉽다.
분석 저장소 흐름
orders / payments / refunds
-> extract by updated_at or CDC
-> staging tables
-> fact_order_payment
-> mart_sales_daily
-> dashboard분석 저장소로 옮긴다는 것은 복제본을 하나 더 만든다는 뜻만이 아니다.
운영 transaction과 분석 정의를 분리하고, 지연과 재계산을 명시한다는 뜻이다.
Spring 서비스 관점
@Transactional(readOnly = true)
public OrderResponse getOrder(Long orderId) {
return orderRepository.findOrderResponse(orderId)
.orElseThrow(OrderNotFoundException::new);
}이 코드는 OLTP 조회에 가깝다.
사용자 요청 안에서 일별 매출이나 cohort 지표를 계산하면 OLAP workload를 API 경로로 끌어들이는 것이다.
API가 필요한 값인지, 몇 분 지연을 허용하는 지표인지 먼저 나눠야 한다.
판단 축
- 사용자 요청의 성공 여부가 걸려 있으면 OLTP 경로로 본다.
- 많은 row를 읽어 추세와 지표를 계산하면 OLAP 경로로 본다.
- 지연을 허용할 수 있으면 운영 DB에서 분리할 후보가 된다.
- 지표 정의가 여러 화면에서 반복되면 mart로 고정할 후보가 된다.
- 운영 DB에서 임시 분석을 했다면 종료 조건과 대체 경로를 둔다.
실패 모델
- dashboard query가 운영 DB connection pool을 점유해 API가 느려진다.
- replica에서 분석 쿼리를 돌렸지만 replica lag 때문에 수치가 흔들린다.
- SQL마다 취소 주문 제외 기준이 달라 매출 수치가 다르다.
- warehouse 적재 지연을 API 정합성 장애처럼 공지한다.
- 분석 table freshness를 측정하지 않아 stale dashboard를 정상으로 본다.
운영 지표
api_db_latency: OLTP 요청이 DB에서 지연되는지 본다.analytics_query_duration: 분석 쿼리 실행 시간이 운영 경계에 영향을 주는지 본다.warehouse_freshness_lag: 운영 데이터와 분석 저장소 사이 지연이다.replica_lag_seconds: 읽기 복제본 사용 시 일관성 위험이다.mart_definition_drift_count: 같은 지표가 여러 SQL로 갈라지는 신호다.
데이터 품질 검증
OLAP은 transaction 정합성 대신 검증 rule로 신뢰를 만든다.
SELECT
(SELECT COUNT(*) FROM orders WHERE created_at::date = DATE '2026-06-30') AS source_count,
(SELECT SUM(order_count) FROM mart_sales_daily WHERE order_date = DATE '2026-06-30') AS mart_count;이 검증은 정확한 business rule을 포함해야 한다.
취소, 환불, 테스트 주문을 source와 mart에서 같은 기준으로 제외하지 않으면 count 비교도 의미가 없다.
개인 프로젝트 기준
개인 프로젝트에서는 운영 DB 안에 summary table을 두는 것부터 시작해도 된다.
다만 API transaction table과 summary table을 분리하고, summary 갱신 시간과 재실행 방법을 남긴다.
운영 DB에서 dashboard를 직접 읽더라도 데이터 양과 쿼리 비용이 커질 때 분리할 기준을 정해 둔다.
기업 운영 기준
기업에서는 운영 DB 보호가 먼저다.
분석 요구가 반복되면 warehouse나 replica, 별도 mart로 분리한다.
분리 후에는 freshness SLA, 적재 실패 알림, 지표 정의 owner가 필요하다.
운영 DB 장애와 분석 지연을 같은 incident로 묶지 않도록 severity 기준도 나눠야 한다.
실전 팁
- API 안에서
GROUP BY가 커지면 OLAP 요구인지 먼저 의심한다. - 운영 DB 직접 분석은 기간, 실행 시간, 종료 조건을 남긴다.
- dashboard 수치는 metric definition 문서와 연결한다.
- warehouse 적재 지연은 사용자 API 장애와 다른 알림 문구를 쓴다.
- OLTP query 튜닝과 OLAP modeling을 같은 작업으로 묶지 않는다.
위험 신호!
- 리포트가 느릴 때 운영 API 인덱스만 추가한다.
- 매출 정의가 controller, repository, dashboard SQL에 흩어져 있다.
- 분석 쿼리가 peak time에 운영 DB에서 실행된다.
- freshness 지표 없이 “오늘 데이터”라고 표시한다.
- warehouse 장애를 해결하려고 운영 DB row를 직접 고친다.
확인 질문
확인 질문
- OLTP와 OLAP을 구분하는 가장 실용적인 기준은 무엇인가?
- 사용자 transaction의 현재 상태를 다루는지, 많은 데이터를 읽어 지표를 계산하는지다.
- 운영 DB에서 dashboard 쿼리를 직접 반복 실행하면 어떤 문제가 생기는가?
- API와 자원을 경쟁하고, 지표 정의가 흩어지고, replica lag나 lock 문제가 운영 장애로 번질 수 있다.
- OLAP 지연은 어떤 지표로 설명해야 하는가?
- warehouse freshness, mart build duration, source와 target count/sum 비교로 설명한다.
참고 문서
- PostgreSQL Documentation
- AWS Analytics Guidance
- Kimball Group, Dimensional Modeling Techniques
- Martin Kleppmann, Designing Data-Intensive Applications