Azure SQL Database를 만들 때 처음 마주치는 선택이 DTU와 vCore입니다. 문서를 읽으면 “DTU는 단순하고 vCore는 유연하다”고 나오는데, 정작 내 경우엔 뭘 골라야 하나에는 답이 안 됩니다.
결론부터 말하면 새로 만드는 거의 모든 경우에 vCore가 맞습니다. 다만 그 이유가 “유연해서”가 아니라 구체적인 세 가지 때문이고, DTU가 나은 예외도 있습니다. 그 기준을 정리하겠습니다.
DTU가 실제로 무엇인가
DTU(Database Transaction Unit)는 CPU·메모리·읽기·쓰기를 하나의 숫자로 뭉뚱그린 단위입니다. Microsoft가 정한 혼합 비율이 있고, 사용자는 그 비율을 바꿀 수 없습니다.
여기서 DTU의 근본적인 문제가 나옵니다. 어느 자원이 부족한지 알 수 없다는 것입니다. DTU 사용률이 90%라고 할 때, CPU가 부족한 건지 IO가 부족한 건지 구분이 안 됩니다. 해결책은 하나뿐입니다 — 다음 티어로 올리기. 그러면 필요 없는 자원까지 함께 사게 됩니다.
실제로 DTU를 구성 요소별로 쪼개 보면 원인이 보입니다.
-- 지난 1시간 자원별 사용률 (DTU가 무엇 때문에 찼는지)
SELECT TOP 60
end_time,
avg_cpu_percent AS CPU,
avg_data_io_percent AS DataIO,
avg_log_write_percent AS LogWrite,
avg_memory_usage_percent AS Memory,
max_worker_percent AS Workers,
max_session_percent AS Sessions,
avg_instance_cpu_percent AS InstanceCPU
FROM sys.dm_db_resource_stats
ORDER BY end_time DESC;
이 쿼리 결과가 vCore로 옮길지 판단하는 근거가 됩니다. 예를 들어 DataIO만 계속 100%이고 CPU는 20%라면, DTU 티어를 올려서 CPU까지 같이 사는 건 낭비입니다. vCore에서 스토리지 성능만 올리는 편이 맞습니다.
max_worker_percent도 눈여겨보세요. 이게 100%에 닿으면 연결이 거부되기 시작합니다. CPU가 여유로워도 워커가 고갈되면 장애가 납니다. DTU 모델에서는 워커 수를 따로 늘릴 방법이 없습니다.
vCore를 권하는 세 가지 이유
1) Azure Hybrid Benefit을 쓸 수 있다
이게 가장 실질적인 이유입니다. DTU 모델에는 Hybrid Benefit이 적용되지 않습니다. SQL Server 라이선스를 Software Assurance와 함께 보유하고 있다면, vCore로 옮기는 것만으로 상당한 절감이 가능합니다.
여기에 예약 인스턴스까지 중첩됩니다. Hybrid Benefit(라이선스 비용 제거) + 3년 예약(컴퓨팅 할인)을 함께 적용하면 종량제 DTU 대비 차이가 꽤 커집니다. 보유 라이선스가 있는데 DTU를 쓰고 있다면 계산해볼 가치가 확실히 있습니다.
2) 컴퓨팅과 스토리지를 따로 조절한다
DTU 모델은 티어마다 스토리지 상한이 묶여 있습니다. 데이터가 커져서 용량이 부족하면 CPU까지 같이 올려야 합니다. vCore에서는 vCore 수와 스토리지 크기를 독립적으로 정합니다.
3) 서버리스와 하이퍼스케일을 쓸 수 있다
둘 다 vCore 전용입니다. 특히 서버리스는 개발·테스트 DB에서 비용을 크게 줄여줍니다. 일정 시간 접속이 없으면 자동으로 일시 중지되고, 그동안 컴퓨팅 요금이 0이 됩니다. 스토리지 요금만 냅니다.
서버리스 계산: 개발 DB에 얼마나 유리한가
실제로 계산해보겠습니다. 개발용 DB를 평일 업무 시간에만 쓴다고 가정합니다.
- 가동 시간: 평일 10시간 × 22일 = 월 220시간 (전체 730시간 중 30%)
- 프로비저닝됨 2 vCore: 730시간 전부 과금
- 서버리스 2 vCore: 220시간만 과금 (나머지는 자동 일시 중지)
서버리스의 시간당 단가가 프로비저닝됨보다 약간 비싸지만(대략 1.5배 수준), 가동 시간이 30%이므로 결과적으로 절반 이하가 됩니다. 대략 0.3 × 1.5 = 0.45, 즉 55% 정도 절감입니다.
다만 서버리스에는 걸림돌이 두 개 있습니다.
- 재개(resume)에 시간이 걸립니다. 일시 중지된 DB에 첫 연결이 들어오면 깨어나는 데 1분 안팎이 걸리고, 그동안 연결은 실패합니다. 애플리케이션에 재시도 로직이 없으면 에러로 보입니다
- 가동률이 높으면 오히려 손해입니다. 단가가 비싸기 때문에 상시 가동 DB에 쓰면 프로비저닝됨보다 비쌉니다. 대략 가동률 60~70%가 손익분기입니다
정리하면 개발·테스트에는 서버리스, 운영에는 프로비저닝됨 + 예약이 기본 공식입니다.
# 서버리스로 DB 생성 (자동 일시 중지 60분)
az sql db create \
--name sqldb-api-dev \
--server sql-api-dev-krc-01 \
-g rg-dev-app \
--edition GeneralPurpose \
--compute-model Serverless \
--family Gen5 \
--min-capacity 0.5 \
--capacity 4 \
--auto-pause-delay 60
--auto-pause-delay를 -1로 두면 자동 일시 중지를 끕니다. 재개 지연이 문제라면 이 값을 늘리는 것으로 조절할 수 있지만, 그만큼 절감 효과는 줄어듭니다.
vCore 안에서도 계층을 골라야 한다
vCore를 택했다면 그 안에서 또 세 가지 서비스 계층이 있습니다. 이 선택이 성능과 비용에 DTU/vCore 결정보다 더 큰 영향을 줍니다.
| 계층 | 스토리지 구조 | 가용성 | 적합한 워크로드 |
|---|---|---|---|
| General Purpose | 원격 프리미엄 스토리지 | 99.99% | 대부분의 업무 시스템 (기본값) |
| Business Critical | 로컬 SSD + 읽기 복제본 | 99.995% | 지연에 민감한 OLTP |
| Hyperscale | 분산 스토리지 (최대 100TB) | 99.95~99.99% | 대용량, 빠른 백업·복원 필요 |
핵심 차이는 스토리지가 로컬이냐 원격이냐입니다. General Purpose는 데이터가 원격 스토리지에 있어서 IO마다 네트워크를 탑니다. Business Critical은 로컬 SSD를 쓰므로 IO 지연이 크게 낮습니다.
앞서 sys.dm_db_resource_stats에서 DataIO가 지속적으로 높게 나온다면, vCore 수를 늘리는 것보다 Business Critical로 계층을 올리는 게 효과적일 수 있습니다. 비용은 대략 2배 이상 뛰지만, vCore를 두 배로 늘려도 IO 병목은 안 풀립니다.
Business Critical의 부가 이점 하나가 읽기 전용 복제본이 무료로 포함된다는 것입니다. 리포팅 쿼리를 복제본으로 보내면 운영 부하가 분산됩니다. 연결 문자열에 옵션 하나만 추가하면 됩니다.
Server=tcp:sql-api-prod-krc-01.database.windows.net,1433;
Database=sqldb-api-prod;
ApplicationIntent=ReadOnly; -- 읽기 복제본으로 라우팅
Authentication=Active Directory Default;
무거운 집계 쿼리나 BI 도구 연결을 여기로 돌리면, 운영 트랜잭션과 자원 경합이 사라집니다. Business Critical 비용을 정당화하는 요소로 함께 계산하시면 됩니다.
크기 조정 전에 쿼리부터 보는 게 순서다
덧붙일 이야기가 있습니다. DTU든 vCore든 계층을 올리는 건 마지막 수단이어야 합니다. 실제로는 인덱스 하나가 빠져서 CPU가 100%인 경우가 훨씬 흔합니다.
-- CPU를 가장 많이 쓴 쿼리 상위 10개
SELECT TOP 10
qs.total_worker_time / 1000 AS TotalCPU_ms,
qs.execution_count,
qs.total_worker_time / qs.execution_count / 1000 AS AvgCPU_ms,
SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset WHEN -1
THEN DATALENGTH(qt.text) ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
ORDER BY qs.total_worker_time DESC;
-- Azure SQL이 추천하는 누락 인덱스
SELECT * FROM sys.dm_db_missing_index_details;
Azure SQL에는 자동 튜닝 기능도 있습니다. 인덱스 생성·삭제와 실행 계획 교정을 자동으로 해줍니다. 운영 DB에 켜두면 사람이 놓친 부분을 상당히 잡아줍니다.
az sql db update --name sqldb-api-prod \
--server sql-api-prod-krc-01 -g rg-prod-data \
--auto-tuning-mode Auto
계층을 올리는 데 드는 월 비용과, 인덱스 하나 추가하는 데 드는 시간을 비교해보면 순서가 명확해집니다.
그래도 DTU가 나은 경우
vCore가 대부분 맞지만 예외가 있습니다.
- 아주 작은 DB — Basic 티어(5 DTU)는 vCore의 최소 구성보다 저렴합니다. 사이드 프로젝트나 소규모 내부 도구에는 이쪽이 쌉니다
- 이미 잘 돌고 있고 라이선스가 없는 경우 — Hybrid Benefit을 못 쓴다면 전환 이득이 크지 않습니다. 굳이 옮길 이유가 약합니다
- 워크로드 특성을 전혀 모를 때 — 단일 숫자로 시작해서 상황을 보는 게 편할 수 있습니다. 다만 위의
sys.dm_db_resource_stats쿼리를 며칠 돌려보면 금방 파악됩니다
전환 방법과 주의사항
DTU에서 vCore로 옮기는 건 생각보다 간단합니다. 서비스 계층 변경만으로 가능하고, 데이터 마이그레이션이 필요 없습니다.
# 현재 구성 확인
az sql db show --name sqldb-api-prod \
--server sql-api-prod-krc-01 -g rg-prod-data \
--query "{tier:sku.tier, name:sku.name, capacity:sku.capacity, maxGB:maxSizeBytes}" -o table
# DTU(S3) -> vCore(GeneralPurpose 2vCore)로 전환
az sql db update --name sqldb-api-prod \
--server sql-api-prod-krc-01 -g rg-prod-data \
--edition GeneralPurpose \
--family Gen5 \
--capacity 2
# Hybrid Benefit 적용 (라이선스 보유 시)
az sql db update --name sqldb-api-prod \
--server sql-api-prod-krc-01 -g rg-prod-data \
--license-type BasePrice
--license-type 값이 헷갈리기 쉽습니다. BasePrice가 Hybrid Benefit 적용(라이선스 보유)이고, LicenseIncluded가 미적용(라이선스 포함 구매)입니다. 직관과 반대라서 잘못 넣는 경우가 있습니다.
전환 시 알아둘 점들입니다.
- 짧은 연결 끊김이 발생합니다. 전환 마지막 단계에서 페일오버가 일어납니다. 재시도 로직이 있으면 대개 무중단처럼 보이지만, 트래픽이 적은 시간에 하는 편이 안전합니다
- 되돌릴 수 있습니다. vCore에서 DTU로도 같은 방식으로 전환됩니다
- DTU와 vCore의 대응 관계는 대략 100 DTU ≈ 1 vCore(General Purpose) 수준으로 보지만, 정확하지 않습니다. 전환 후 실제 사용률을 다시 재보세요
정리
sys.dm_db_resource_stats로 어느 자원이 병목인지 먼저 확인한다- SQL Server 라이선스가 있으면 vCore + Hybrid Benefit이 거의 확정적으로 유리하다
- 개발·테스트 DB는 서버리스로 (가동률 60% 미만일 때)
- 운영 DB는 프로비저닝됨 + 예약 인스턴스
- 아주 작은 DB는 DTU Basic이 여전히 가장 싸다
- 전환은 서비스 계층 변경만으로 되고 되돌릴 수 있다
약정 할인 전반은 Reserved·Savings Plan·Spot 선택 기준에, 비용이 이미 늘어난 상태라면 Cost Analysis로 원인 찾기를 참고하세요.