실험 목록으로 돌아가기
E012완료P1

DSQL의 대용량 조회·집계와 OLTP 간섭

DSQL의 큰 쿼리 성능·OLTP 간섭·튜닝 부담은?

결과 요약

이 실험은 DSQL에서 큰 JOIN·집계 쿼리가 얼마나 걸리고 비용이 얼마인지, 그리고 이런 쿼리를 주문 업무(OLTP)와 동시에 실행하면 OLTP가 얼마나 느려지는지를 확인했습니다. 최소 범위(MVP)로, 계획의 L 규모 대신 E002의 S 규모 데이터(주문 1,100만, 주문 품목 2,750만 행)에서 선택도가 다른 네 쿼리를 실행했고, 초당 1,000건의 OLTP 부하 중 집계를 반복하는 간섭 시험을 했습니다. 대조군은 이번에 측정하지 않았습니다.

인덱스를 쓰는 고객별 최근 주문 20건 JOIN은 30회 실행에서 p50 4.4 ms, p95 32.9 ms였습니다. 주문 10%(약 110만 행)를 날짜별로 집계하는 쿼리는 2.4–2.6초, 주문 1% 범위의 주문 품목(약 27만 행)으로 상품 순위를 매기는 window 쿼리는 0.7초, 주문 1,100만 행 전체를 상태별로 집계하는 쿼리는 약 36초가 걸렸습니다. 같은 쿼리를 두 번 실행한 결과 행 수와 결과 해시가 같았고, 두 번째 실행도 첫 번째와 거의 같은 시간이 걸려 반복 실행으로 빨라지는 효과는 보이지 않았습니다.

DSQL은 쿼리가 처리한 양만큼 DPU로 과금합니다. 분 단위 사용량으로 추정하면 전체 집계 한 번에 약 1,700 DPU(약 $0.017), 10% 집계 한 번에 약 100–150 DPU가 들었습니다. 초당 1,000건의 OLTP 부하를 보내면서 10% 집계를 쉬지 않고 반복(5분 동안 124회, p50 2.4초)하자, OLTP는 실패 0건으로 SLO를 지켰고 주문 생성 p95가 27.5 ms에서 32.0 ms로, p99가 30.7 ms에서 41.8 ms로, 상품 조회 p99가 6.9 ms에서 16.4 ms로 늘었습니다.

프로덕션 사용 관점

DSQL에서 인덱스를 타는 조회는 빠르지만, 수백만 행 이상을 훑는 집계는 초 단위에서 수십 초가 걸렸고(1,100만 행 약 36초), 트랜잭션 300초 한도 때문에 더 큰 집계는 나눠 실행해야 합니다. 서버 쪽 statement_timeout과 문장 취소가 동작하지 않으므로(E001), 오래 걸리는 쿼리를 중간에 멈출 수단도 제한됩니다. 집계를 반복해도 OLTP는 목표 안에서 처리되어 간섭은 작았습니다. 다만 집계는 처리한 데이터만큼 DPU 요금이 나오므로, 정기 리포트나 대시보드처럼 큰 집계가 잦은 업무는 분석용 저장소로 분리하는 편이 비용 면에서 안전합니다. 대조군과의 속도 비교는 하지 않았습니다.

확인할 질문

DSQL의 큰 쿼리 성능·OLTP 간섭·튜닝 부담은?

실행 조건

  • 리전과 일시: 서울(ap-northeast-2), 2026-09-29 10:53–11:07 UTC.
  • 구성: D1 Aurora DSQL 단일 리전, E002 규모 데이터(주문 1,100만, 주문 품목 2,750만, 원장 1,100만 행, 약 5 GiB)와 앞선 측정이 쌓은 행. E002 2차 측정과 같은 클러스터입니다.
  • 쿼리:
    • 고객별 최근 주문: orders와 order_items JOIN, 고객 ID 조건, 최근 20건(인덱스 orders_customer_created 사용). 30회.
    • 일별 매출(10%): orders의 id < 1,100,000 범위를 날짜별 count·sum. 2회.
    • 상품 순위(1%): 주문 ID < 110,000인 주문 품목을 상품별로 합한 뒤 rank() window. 2회.
    • 상태별 전체 집계: orders 전체를 상태별 count·sum. 2회.
  • DPU 추정: 쿼리 사이에 90초씩 쉬게 하고 CloudWatch TotalDPU 분 합계를 쿼리 구간에 맞춰 나눴습니다. 분 단위 집계라 쿼리별 값은 근사치입니다.
  • 간섭 시험: 고정 도착률 1,000 TPS OLTP(워밍업 60초 + 측정 300초) 동안 한 연결이 10% 집계를 쉬지 않고 반복했습니다. 비교 기준은 같은 클러스터에서 앞서 측정한 E008의 부하만 셀입니다.
  • 부하 발생기: m7g.4xlarge Spot 러너 1대.
  • 계획과 달라진 점: L 데이터, JSON 조건 조회, 집계 동시성 1/4/16 탐색, 20분 × 3회 측정, 대조군과 reader 분리 조건은 실행하지 않았습니다.

성능 결과

쿼리 처리 범위 결과 행 실행 시간 DPU(추정)
고객별 최근 주문 인덱스 범위 20 p50 4.4 ms, p95 32.9 ms, p99 80.8 ms 무시할 수준
일별 매출(10%) 주문 약 110만 행 90 2.61초, 2.39초 약 100–150
상품 순위(1%) 주문 품목 약 27만 행 10 0.69초, 0.66초 약 10
상태별 전체 집계 주문 1,100만 행 이상 2 36.3초, 35.9초 약 1,700

OLTP 1,000 TPS에서 집계 반복 유무에 따른 p95 / p99(ms). 두 셀 모두 실패 0, 불변식 위반 0건, SLO 통과.

업무 부하만(E008 기준 셀) 10% 집계 반복 중
상품 조회 6.0 / 6.9 6.4 / 16.4
주문 이력 8.7 / 9.8 11.8 / 23.5
주문 생성 27.5 / 30.7 32.0 / 41.8
주문 취소 27.0 / 29.2 28.1 / 39.8
  • 간섭 시험 중 10% 집계는 124회 모두 성공했고 p50 2.42초, p99 2.66초였습니다. 단독 실행(2.4–2.6초)과 같아, OLTP가 집계를 느리게 만들지도 않았습니다.
  • 간섭 구간의 DSQL 사용량은 분당 약 4,400 DPU로, OLTP만 있을 때(분당 약 1,800 DPU로 추정)보다 약 2.4배였습니다.

개발·운영 편의성

  • 같은 쿼리를 반복해도 실행 시간이 거의 같아, 첫 실행과 반복 실행을 나눠 튜닝할 여지(캐시 효과)는 이번 쿼리에서 보이지 않았습니다.
  • DSQL은 work_mem 같은 메모리 설정이나 실행 중 쿼리 취소 수단을 사용자가 조정할 수 없습니다. 쿼리를 빠르게 하려면 인덱스와 쿼리 범위를 바꾸는 방법이 주된 수단입니다.
  • 큰 집계는 300초 트랜잭션 한도를 넘으면 거절되므로, 데이터가 계속 커지는 집계는 범위를 나눠 실행하도록 설계해야 합니다.

비용

같은 클러스터를 쓴 E002 2차 측정의 일부로, 이 시험 구간(10:54–11:09 UTC)의 DSQL 사용량은 27,921 DPU(약 $0.28)였습니다. 클러스터와 러너 비용은 E002 보고서의 비용 절에 포함했습니다.

결론과 한계

  • DSQL은 인덱스 조회는 빠르고, 큰 집계는 처리한 행 수에 비례해 느려지고(1,100만 행 약 36초) DPU 요금이 나왔습니다. 집계 반복이 OLTP에 준 간섭은 작았습니다.
  • 한계: S 데이터, 1회 실행, 각 쿼리 2회, DSQL 단독입니다. 대조군과의 속도·비용 비교와 L 데이터에서의 동작은 측정하지 않았습니다. DPU는 분 단위 합계로 나눈 근사치입니다.

정리 기록

  • 이 시험은 E002 2차 측정 실행(e002-20260929t081139z-4dce)의 클러스터와 러너를 썼습니다. 자원은 11:08–11:10 UTC에 삭제했고, e002.py verify의 remaining_count=0(11:10:30 UTC)과 수동 교차 확인(DSQL 클러스터·실험 VPC·실험 IAM 역할·열린 Spot 요청 0개)을 마쳤습니다.