콘텐츠로 이동

OLTP와 OLAP는 왜 저장 방식이 달라지는가

같은 주문 데이터인데 실시간 결제와 월간 매출 보고서가 서로 다른 데이터베이스 구조를 요구하는 이유를 설명합니다.

예상 읽기 시간 7분 · 핵심 질문: 한 저장소에서 거래와 분석을 함께 처리해도 되는가

쇼핑몰의 결제 요청은 주문 한 건과 재고 몇 행을 빠르고 정확하게 바꿔야 한다. 반면 월간 매출 보고서는 수천만 건에서 날짜와 금액 열을 조회해 합계를 계산한다. 둘 다 주문 데이터를 사용하지만, 조회 범위와 기다릴 수 있는 시간, 동시 수정의 중요도가 다르다.

이 차이를 무시하고 “데이터가 같으니 같은 데이터베이스에서 처리하면 된다”고 생각하면 분석 질의 하나가 메모리와 저장 장치 대역폭을 사용해 사용자 결제를 늦출 수 있다. 반대로 데이터가 조금 늘었다는 이유만으로 분석 시스템을 분리하면 복제 지연과 운영 대상만 늘어난다. 먼저 제품 이름이 아니라 작업의 모양을 분류해야 한다.

한 건을 바꾸는 일과 전체를 읽는 일

OLTP(Online Transaction Processing, 온라인 트랜잭션 처리)는 주문 생성, 재고 차감, 잔액 변경처럼 짧은 거래를 많이 처리한다. 한 요청이 읽고 쓰는 행은 적지만 여러 요청이 같은 상품이나 계좌를 동시에 바꿀 수 있다. 그래서 낮은 개별 지연, 빠른 인덱스 탐색, 트랜잭션과 충돌 처리가 중요하다.

OLAP(Online Analytical Processing, 온라인 분석 처리)는 긴 기간의 매출 합계, 사용자 행동 집계처럼 많은 행을 읽어 그룹화하고 계산한다. 개별 행을 즉시 바꾸는 속도보다 필요한 열만 읽는 능력, 압축률, 병렬 처리량이 중요하다. 한 질의가 CPU와 메모리를 오래 사용할 수 있으므로 사용자 요청과 같은 자원을 쓰면 꼬리 지연이 커질 수 있다.

이 이름들은 제품의 등급이 아니라 작업 유형이다. PostgreSQL에서도 분석 질의를 실행할 수 있고, 분석 제품도 데이터를 추가한다. 질문은 “실행할 수 있는가”가 아니라 대표 부하에서 다른 작업의 목표를 해치지 않고 지속할 수 있는가이다.

행 저장과 열 저장은 조회하는 바이트가 다르다

행 저장은 주문 한 건의 식별자, 회원, 금액, 상태를 물리적으로 가까이 둔다. 기본 키로 주문 하나를 찾고 여러 열을 함께 읽거나 수정할 때 적은 페이지 접근으로 끝내기 좋다. PostgreSQL과 InnoDB를 비롯한 일반적인 관계형 거래 저장소가 이 방향에 가깝다.

열 저장은 여러 주문의 금액끼리, 날짜끼리 모아 둔다. “전체 주문의 금액 합계”를 계산할 때 주소나 상태 같은 필요 없는 열을 읽지 않아도 된다. 같은 자료형과 비슷한 값이 이어져 압축하기 쉽고, CPU가 여러 값을 묶어 계산하는 벡터화 실행에도 유리하다. 대신 한 주문의 전체 열을 즉시 업데이트하는 경로는 더 복잡해질 수 있다.

flowchart TB
  Q1["주문 한 건 조회·수정"] --> R["행 저장: 한 주문의 여러 값을 가까이 배치"]
  Q2["전체 주문의 금액·날짜 집계"] --> C["열 저장: 같은 열의 값을 연속 배치"]
  R --> R1["적은 행을 빠르게 찾고 변경"]
  R --> R2["많은 행에서 일부 열만 읽으면 불필요한 바이트 증가"]
  C --> C1["필요한 열만 읽고 압축·병렬 계산"]
  C --> C2["한 행 전체를 자주 변경하면 조합 비용 증가"]

논리적으로 같은 표라도 물리 배치는 다를 수 있다. 저장 방식은 스키마의 겉모양이 아니라 실제로 읽는 페이지 수, CPU 캐시 사용, 압축률과 쓰기 증폭을 바꾼다.

같은 서버에서 둘이 경쟁할 때 생기는 일

거래 요청은 보통 짧기 때문에 평균 지연만 보면 안정적으로 보인다. 하지만 분석 질의가 많은 페이지를 읽으면 거래에 필요한 페이지가 버퍼 캐시에서 밀려날 수 있다. 대규모 정렬과 집계는 CPU와 임시 저장 공간을 사용하고, 복제본에서 실행하더라도 복제 적용과 같은 자원을 경쟁할 수 있다.

이때 관찰할 것은 “분석 질의가 몇 개 있는가”보다 영향이다. 분석이 시작된 뒤 거래 요청의 p95·p99 지연이 변하는지, 버퍼 적중률과 저장 장치 읽기량이 어떻게 달라지는지, 복제 지연이 누적되는지 본다. 목표 안에 있으면 같은 시스템을 유지하는 편이 단순하다.

분리가 필요하면 보통 원본 OLTP에서 변경 데이터 캡처(CDC, Change Data Capture)나 배치 적재로 분석 저장소에 복사한다. 거래 장애와 분석 부하를 격리할 수 있지만 데이터가 도착하는 지연, 중복 처리, 재적재와 스키마 변경을 운영해야 한다.

HTAP가 두 비용을 없애 주는 것은 아니다

HTAP(Hybrid Transactional/Analytical Processing, 혼합 트랜잭션·분석 처리)는 최신 거래 데이터를 별도 이동 지연 없이 분석하려는 접근이다. 한 시스템 안에서 행 표현과 열 표현을 함께 유지하거나, 역할이 다른 복제본을 같은 논리 체계로 제공할 수 있다.

방금 들어온 주문까지 즉시 분석해야 하고 별도 데이터 이동 경로의 운영 비용이 큰 경우 매력적이다. 그러나 거래와 분석이 같은 CPU·메모리·저장 대역폭을 경쟁할 수 있고, 두 표현을 동기화하는 비용도 남는다. “HTAP가 최신이므로 선택한다”가 아니라 다음 조건을 확인해야 한다.

  • 분석 결과가 몇 초 또는 몇 분 늦어도 되는가?
  • 분석이 몰릴 때 거래의 p99 지연을 어떻게 격리하는가?
  • 행 표현과 열 표현의 동기화가 지연되면 어떤 값을 보여 주는가?
  • 별도 분석 저장소와 데이터 이동 경로를 운영하는 비용보다 실제로 단순한가?

분석이 드물고 몇 분의 지연을 허용한다면 별도 배치나 CDC 경로가 장애 격리 면에서 더 명확할 수 있다. 반대로 실시간 위험 탐지처럼 최신 거래와 넓은 분석을 함께 봐야 한다면 HTAP가 검토 대상이 된다.

분리 결정을 내릴 때 기록할 수치

제품을 바꾸기 전에 거래와 분석을 같은 시간축에서 측정한다. 거래는 초당 요청 수, 한 요청이 읽고 쓰는 행 수, 잠금 대기, p95·p99 지연을 본다. 분석은 스캔한 바이트, 사용한 열의 비율, 동시 질의 수, 메모리와 임시 저장 공간을 본다. 함께 실행했을 때 버퍼 적중률, 저장 장치 대역폭, 복제 지연이 어떻게 변하는지도 기록한다.

결정 문장은 “데이터가 커져서 분석 DB를 도입한다”보다 구체적이어야 한다. 예를 들어 “월말 집계 중 결제 p99가 목표를 넘고, 집계가 읽는 열은 전체 열의 15%뿐이므로 열 저장 분석 경로를 분리한다. 최대 5분의 데이터 지연을 허용하고 CDC 재처리 절차를 운영한다”처럼 쓰면 나중에 조건이 달라졌을 때 다시 판단할 수 있다.

참고 자료