2026년 논문 네 편은 버전 관리, 충돌 판정, 재실행 비용이 단일 엔진과 다른 계층에 놓이는 설계를 보여 줍니다. 단일 엔진 안에서 내린 MVCC 같은 결정은 비용이 쌓이는 계층을 기준으로 다시 따져야 한다는 것이 이 글의 판단입니다.
다중 버전 동시성 제어(Multi-Version Concurrency Control, MVCC)는 단일 엔진에서 긴 읽기와 짧은 쓰기를 함께 처리하기 위한 선택이었습니다. 버전 관리, 충돌 판정, 로그 재실행이 모두 같은 엔진 안에서 일어났으므로 비용도 한곳에서 계산했습니다. MVCC의 기본 동작은 데이터베이스 트랜잭션과 MVCC에 정리했습니다.
클라우드 OLTP(Online Transaction Processing)는 쓰기 계산 계층, 로그와 데이터의 저장 계층, 읽기 복제본과 분석 엔진을 따로 둡니다. 2026년에 공개된 네 편의 논문은 이런 분리 구조와 주-백업 복제에서 버전 관리, 충돌 판정, 재실행 비용이 단일 엔진과 다른 계층에 놓이는 설계를 보여 줍니다. 세 편은 클라우드 OLTP를 다루고, Ira는 Ethereum의 주-백업 복제를 다룹니다.
네 논문 중 어느 것도 같은 워크로드에서 비용의 위치만 바꿔 총비용을 비교하지는 않았습니다. 그래도 같은 기법의 손익은 비용을 내는 계층에 따라 달라질 수 있으므로, 설계를 고르기 전에 이 위치부터 확인해야 한다고 판단합니다.
주 인스턴스에서 버전을 빼자는 제안
CIDR'27에 채택된 논문(arXiv:2610.15793, 2026-10)은 클라우드 OLTP의 주 인스턴스에서 MVCC를 빼자고 주장합니다. 대안은 객체마다 물리 버전을 하나만 두는 단일 버전 동시성 제어(Single-Version Concurrency Control, SVCC)입니다. 근거는 Aurora, Socrates, Taurus, PolarDB 같은 단일 작성자 구조입니다.
단일 작성자 구조에서는 주 인스턴스 하나가 모든 쓰기를 맡고, 긴 분석 질의는 복제본이나 별도 분석 엔진이 처리합니다. 논문은 MVCC의 주 이점인 비차단 읽기를 엔진 내부의 동시성 제어 대신 이 배포 구조가 제공한다고 봅니다.
그러면 주 인스턴스의 MVCC에는 버전 저장, 가비지 컬렉션(Garbage Collection, GC), 튜플 메타데이터의 비용만 남는다는 것이 논문의 논리입니다. 논문이 인용한 선행 연구에서 가시성 메타데이터는 레코드당 보통 16~32바이트 이상입니다.
저자들은 LeanStore 위에 두 프로토콜을 직접 구현해 복잡도를 비교했습니다. SVCC 쪽은 2단계 잠금(Two-Phase Locking, 2PL)에 Wait-Die 교착 상태 예방(동시성 제어와 동기화 참고)을 붙였습니다. MVCC 쪽은 HyPer 방식(제자리 갱신, undo 로그, 커밋 시 검증)을 따르되 술어 검증 대신 키 단위 검증을 씁니다.
| 항목 | SVCC | MVCC |
|---|---|---|
| 핵심 구현 | 303줄 | 426줄 |
| 통합을 위한 수정 | 45줄 | 265줄 |
| 테스트 | 665줄 | 1,325줄 |
| TPC-C 처리량(8스레드, 짧은 실행, 논문 표기 serializable) | 127K txn/s | 119K txn/s |
저자들은 MVCC의 공학 비용을 약 2~3배로 요약합니다. 세 항목을 합하면 1,013줄과 2,016줄로 약 2배입니다.
비율 차이가 가장 큰 항목은 통합 수정(약 5.9배)이고, 절대 줄 수 차이는 테스트(660줄)가 가장 큽니다. 저자들은 핵심 구현과 통합 수정의 차이를 주로 버전 체인과 인덱스의 통합 때문이라고 설명합니다.
처리량 비교는 해석 범위가 좁습니다. 원문은 이 실행을 가벼운 TPC-C 실행이라고 부르며, 비교의 초점이 성능보다 복잡도에 있다고 밝힙니다.
저자들은 두 구현 모두 Intel TBB(Threading Building Blocks) 동시 해시 테이블의 오버헤드가 크다고 적습니다. 실행이 짧아 GC 같은 2차 효과가 거의 나타나지 않았다는 점도 밝힙니다. 두 구현은 범위 잠금 없이 키 단위로 동기화해 팬텀 읽기를 허용하며, 하드웨어와 웨어하우스 수는 본문에 없습니다.
긴 트랜잭션은 남은 문제입니다. 논문은 트랜잭션 크기와 시간 제한, 경량 스냅샷, 투기적 실행을 확장으로 제안하지만 셋 다 향후 과제로 남겼습니다. 이 확장들의 구현과 측정 결과는 없습니다.
운영 수치로 드러난 버전 정리 비용
SQL Azure 버전 클리너 논문(PVLDB 19(12), 2026)은 엔진 안에 남은 MVCC 정리 비용을 운영 텔레메트리로 보여 줍니다. SQL Azure는 행을 제자리에서 갱신하고 이전 버전을 행 안이나 영구 버전 저장소(Persistent Version Store, PVS)에 남깁니다. 이 버전은 기본 격리 수준인 RCSI(Read Committed Snapshot Isolation) 같은 스냅샷 읽기에 쓰입니다. 롤백된 트랜잭션이 남긴 부분 갱신을 되돌리는 데에도 쓰입니다.
이 논문은 SQL Azure Hyperscale의 참고 문헌으로 Socrates 논문을 인용합니다. SVCC 논문이 단일 작성자 구조의 예로 든 시스템 계열에서도 MVCC 정리가 운영 문제로 남아 있었다는 뜻입니다.
필요 없어진 버전은 백그라운드 클리너가 회수하며, 저자들이 운영 텔레메트리에서 찾은 클리너의 문제는 세 가지입니다. 단일 스레드 클리너는 100TB를 넘을 수 있는 Hyperscale 데이터베이스에서 활동이 많을 때 전체 스윕에 1주일 이상 걸리기도 했습니다. 갱신이 잦은 워크로드에서는 클리너가 잠금을 얻지 못해 정리를 미뤘고, 중단되거나 오래 실행되는 트랜잭션은 정리 기준선의 전진을 늦췄습니다.
| 개선 | 집계 조건 | 결과 |
|---|---|---|
| 동적 병렬 정리 | PVS 100GB 초과 데이터베이스, 30일 | P99.99 스윕 시간이 병렬 정리 없이 약 6일, 사용 시 약 1일(일반적인 경우는 큰 차이 없음) |
| 트랜잭션 단위 버전 추적 | 스윕이 4시간 이상인 경우, 30일 | 회수된 PVS의 약 60% 담당 |
| 문장 단위 정리(RCSI) | 스냅샷 기준선(MinUsefulXTS) 때문에 PVS 50GB 초과 보류, 30일 | 회수된 PVS의 약 27% 담당 |
| 사이드 리스트와 사용자 보조 정리 | 10일, 전체 스윕 약 3억 8,500만 회 | 충돌 워크로드 영향 약 376만 회, 성공률 98.6% 초과, 실패 약 5만 2천 회 |
사용자 보조 정리는 충돌하는 테이블 잠금을 쥔 사용자 트랜잭션에 정리 작업을 넘기는 방식입니다. 정리 비용 일부를 백그라운드 작업에서 전경 트랜잭션으로 옮긴 설계이며, 현재는 배타 잠금을 쥔 경우에만 동작합니다.
마지막 행의 성공률과 실패 횟수는 원문 그대로 옮겼습니다. 98.6%와 실패 약 5만 2천 회는 서로 맞지만(5.2만/376만 ≈ 1.4%), 논문이 같은 집계에서 적은 성공 323만 회는 약 86%에 해당해 둘과 맞지 않습니다. 따라서 정확한 성공률은 논문만으로 확정할 수 없습니다.
이 개선들은 1,200만 개가 넘는 데이터베이스에서 실행 중이며, 효과는 운영 텔레메트리로만 평가했습니다. TPC-C와 TPC-E는 트랜잭션이 짧아 PVS가 정리 임계값에 도달하지 않으므로, 저자들은 두 벤치마크를 회귀 검증에만 썼습니다. SVCC 논문의 TPC-C 비교도 실행이 짧아 GC 효과가 작았다고 적었으므로, 두 논문 모두 짧은 벤치마크로는 이 비용이 드러나지 않았습니다.
커밋으로 모은 조정과 시간으로 정한 GC
Aurora DSQL 논문(arXiv:2607.13276, 2026-07)은 계산, 저장소, 트랜잭션 조정을 독립된 서비스로 나눈 구조를 설명합니다. 쿼리 프로세서(Query Processor, QP)는 시작 시각의 스냅샷으로 저장 노드를 읽고, UPDATE 같은 쓰기는 QP 안에 버퍼로만 둡니다. 충돌 판정은 커밋 시점에 Adjudicator가 맡고, 커밋된 변경의 내구성과 복제는 Journal이 맡습니다.
flowchart LR
C["클라이언트"] -->|"SQL"| Q["QP<br/>스냅샷 읽기, 쓰기 버퍼"]
Q -->|"시작 시각 기준 읽기"| S["저장 노드<br/>MVCC 버전, 시간 기준 GC"]
Q -->|"COMMIT, 쓰기 집합"| A["Adjudicator<br/>쓰기-쓰기 충돌 판정"]
A -->|"논리적 사후 이미지"| J["Journal<br/>내구성과 복제"]
J --> X["Crossbar<br/>저장 샤드별 병합 정렬"]
X -->|"변경 적용"| S
이 구조에서 읽기와 문장 실행은 리전 안에서 끝나고, 리전 사이 조정은 커밋에 모입니다. 아래 지연은 단순한 기본키 트랜잭션으로 잰 마이크로벤치마크 결과(논문 그림 6)입니다.
us-east-1과 us-east-2에 걸치고 us-west-2를 witness로 둔 클러스터에서 기본키 SELECT의 p99는 약 2ms, UPDATE는 약 3ms였습니다. COMMIT의 p99는 이 다중 리전 구성에서 약 30ms, 단일 리전 구성에서 7.4ms였고, 두 주 리전 사이 왕복 시간의 p99는 14.4ms입니다.
충돌 판정은 낙관적 동시성 제어(Optimistic Concurrency Control, OCC)입니다. Adjudicator는 트랜잭션의 시작과 커밋 사이에 다른 트랜잭션이 같은 키를 썼는지 검사합니다.
기본이자 유일한 격리 수준이 strong snapshot isolation이므로 읽기-쓰기 충돌로는 abort하지 않고 write skew를 허용합니다. 카탈로그와 FOR UPDATE 같은 예외에만 읽기-쓰기 충돌 검사를 더합니다.
조정 비용은 커밋 시점의 abort와 재시도로 나타납니다. 여러 Adjudicator에 걸친 트랜잭션은 2단계 커밋(Two-Phase Commit, 2PC) 변형으로 투표합니다. 관여하는 Adjudicator가 많을수록 커밋 지연이 커진다고 논문은 적습니다.
조정을 커밋 경계로 미루는 다른 설계는 에포크 기반 낙관적 동시성 제어에, 커밋 로그가 정합성을 맡는 흐름은 2PC에서 커밋 로그로 옮겨간 정합성에 정리했습니다.
DSQL은 MVCC 버전을 저장 계층에 둡니다. 논문은 어느 구성 요소도 실행 중인 트랜잭션의 전체 목록을 알지 못하므로 이 구조에서 GC가 특히 어렵다고 적습니다. 그래서 트랜잭션 실행 시간에 상한을 두고, 각 저장 서버가 일정 시간보다 오래된 이전 버전을 다른 서버와 조정하지 않고 버립니다.
현재 이 시간은 5분이며, 이보다 오래된 시작 시각으로 읽기가 들어오면 저장 노드가 요청을 거부하고 트랜잭션은 실패합니다. 저자들은 이 방식이 분석이나 OLAP(Online Analytical Processing) 시스템에는 맞지 않는다고 보고, 분석 용도에는 변경 데이터 캡처 스트림을 제공합니다. SQL Azure가 전역 워터마크로 정하는 정리 시점을 DSQL은 트랜잭션 길이 제한으로 정합니다.
DSQL은 GC와 다른 근거로 트랜잭션당 수정 행을 3,000개, 데이터를 10MiB로 제한합니다. 논문은 꼬리 지연을 제한해야 한다는 운영 경험을 근거로 들고, 리틀의 법칙을 부분적인 이유로 덧붙입니다. 논문은 이 제한에 대한 고객 피드백이 예상보다 많았고, 크기를 더 제어할 수 있게 바꾸는 작업을 하고 있다고 적습니다.
재실행 쪽 작업의 위치도 다릅니다. Journal에는 인덱스 변경까지 포함한 논리적 사후 이미지가 기록되고, 인덱스 변경은 QP가 커밋 전에 계산합니다. 저장 노드는 이 기록을 로컬 읽기-수정-쓰기 없이 결정적으로 적용할 수 있으며, 서로 조정하지 않습니다.
대신 저장 노드는 읽기 시각 이하의 커밋을 모두 받았음을 확인한 뒤에 응답합니다. Adjudicator가 heartbeat로 커밋 시각을 물리 시계에 맞춰 전진시키고, 저장 노드가 그 시각까지 따라오지 못했으면 읽기가 기다립니다. 논문은 Aurora PostgreSQL 같은 단일 작성자 설계가 복제본 읽기에서 최종 일관성을 노출한다고 비교합니다.
재실행 비용을 주 복제본으로 옮기는 힌트
Ira 논문(arXiv:2601.21286, 2026-01 공개, 2026-08 v3)은 Ethereum 실행 클라이언트 reth의 주-백업 복제를 다룹니다. 계산과 저장소를 나눈 클라우드 OLTP 사례는 아니며, 이 글에서는 재실행 비용을 노드 사이에서 옮기는 설계의 근거로만 씁니다.
백업은 주 복제본이 실행한 트랜잭션을 다시 실행해 상태를 맞추며, 논문은 합의 지연이 이 재실행 시간에 묶인다고 봅니다. Ira에서는 주 복제본이 실행 중에 모은 접근 키 집합을 힌트로 보내고, 백업은 이 힌트로 데이터를 미리 읽습니다.
실험은 Ethereum 메인넷 100,800블록을 대상으로, 실행 전마다 OS 페이지 캐시를 비우고 수행했습니다. 장비는 Apple M1 Pro 10코어, 32GB 메모리, USB 외장 케이스에 넣은 8TB NVMe SSD입니다.
| 측정 | 기준 reth | Ira |
|---|---|---|
| 주 복제본 전체 시간 | 23,250초 | 29,889초(+28.6%) |
| 백업 전체 시간, 사전 읽기 1스레드 | 22,604초 | 4,366초(5.2배) |
| 백업 전체 시간, 사전 읽기 16스레드 | 22,604초 | 956초(23.6배) |
| 백업 전체 시간, 사전 읽기 64스레드 | 22,604초 | 871초(25.9배) |
주 복제본과 백업의 기준 시간은 서로 다른 측정값입니다. 초록의 10.9%는 힌트 생성과 직렬화 시간 1,719초를 실행 시간 합계 15,717초로 나눈 값입니다. 전체 시간 증가율은 28.6%이며, 저자들은 나머지 증가를 메모리 압력과 캐시 간섭 같은 계측의 2차 효과로 설명합니다.
저자들은 힌트 작업을 다음 블록 실행과 겹치면 실효 비용이 0에 가까워진다고 주장하지만, 이 파이프라인은 측정하지 않았습니다. 압축 힌트의 크기는 블록당 중앙값 46.5KB입니다.
다른 구간에서는 효과가 작았습니다. 2024년 9~10월의 블록 100,001개 구간에서는 16스레드 백업 단축이 10.1배, 힌트 비용이 7.3%였습니다. 저자들은 이 차이를 워크로드 효과로 설명합니다.
꼬리 구간도 남습니다. 사전 읽기 1스레드에서는 블록의 3.02%가 기준보다 느렸고, 64스레드에서는 0.09%였습니다. 존재하지 않는 키를 담은 악성 힌트로 무작위 1,000블록을 16스레드로 재실행하면 중앙값 1.58배, P99 8.3배 느려졌고 81.5%의 블록이 느려졌습니다.
논문은 힌트를 권고 정보로 다루므로 잘못된 힌트가 성능에만 영향을 주고 정확성에는 영향을 주지 않는다고 설명합니다. 적용 조건으로는 먼저 실행하는 노드가 있는 주-백업 구조, 저장장치 I/O가 병목인 재실행, 결정적 실행을 듭니다.
PostgreSQL 스트리밍 복제나 MySQL 그룹 복제 같은 데이터베이스 적용은 통합 스케치로만 제시했고 측정하지 않았습니다. 저자들은 구현이 단일 스레드 실행 모델을 대상으로 한다는 점도 한계로 밝힙니다.
Ira는 백업의 I/O 대기를 주 복제본의 실행 시간으로 옮기며, 저자들은 백업이 많을수록 이득이 커진다고 봅니다. 단일 작성자 클라우드 OLTP에서는 주 인스턴스가 쓰기 처리량의 상한입니다. 이 방식을 그 구조에 적용하면 주 인스턴스의 시간 증가(Ethereum 실험에서 28.6%)는 SVCC 논문이 줄이려는 비용과 같은 계층에 쌓입니다. 이는 판단입니다.
주장이 성립하지 않는 조건
SVCC 논문도 주 인스턴스의 스냅샷 읽기가 ms 단위 복제 지연이 있는 복제본 읽기보다 신선하다고 인정합니다. 쓰기와 막히지 않고 최신 스냅샷을 읽어야 한다면 비차단 읽기를 배포 구조에 맡길 수 없습니다. SVCC가 제안한 경량 스냅샷은 구현되지 않았습니다. 이는 판단입니다.
DSQL은 저장 노드가 읽기 시각까지 따라오기를 기다리게 해서 이 신선도를 제공합니다. 이때 비용은 저장 계층의 읽기 대기로 나타납니다.
SQL Azure는 버전 저장소를 스냅샷 읽기 외에 Constant Time Recovery 같은 복구 기능에도 씁니다. SVCC 논문은 버전을 뺄 때 이런 기능을 무엇으로 대신할지 다루지 않습니다. 주 인스턴스에서 버전을 빼면 복구 시간 같은 다른 지표에서 비용이 생길 수 있습니다. 이는 추정입니다.
고경합 조건도 비어 있습니다. SVCC 논문의 관련 연구 절은 CCBench 연구(Tanabe 외, 2020)를 인용해 MVCC가 고경합 같은 제한된 경우에만 SVCC보다 낫다고 씁니다. 그러나 고경합 워크로드에서 SVCC 프로토타입을 측정한 결과는 논문에 없습니다.
SVCC는 긴 트랜잭션에 크기와 시간 제한을 제안하고, DSQL은 트랜잭션을 5분, 3,000행, 10MiB로 제한합니다. SQL Azure는 제한 대신 문장 단위 정리로, 긴 스냅샷이 끝나기 전에 그 스냅샷에 묶인 PVS 일부를 회수합니다. SVCC와 DSQL의 제한은 대량 적재 같은 작업을 애플리케이션이 나누게 하므로, 비용을 없애지 않고 다른 주체에 넘깁니다. 이는 판단입니다.
SVCC 논문은 현대 엔진이 직렬성(serializability)을 실용적으로 만들었다고 주장합니다. DSQL은 snapshot isolation을 택한 이유 중 하나로 직렬성이 요구하는 읽기-쓰기 충돌 abort를 피할 수 있다는 점을 듭니다. 실행 중 잠금을 쓰는 단일 주 인스턴스와 커밋 시점에 검증하는 분산 커밋은 직렬성 비용을 내는 위치가 다르므로, 한쪽 결론을 다른 구조에 그대로 옮기기 어렵습니다. 이는 판단입니다.
네 논문이 답하지 못한 질문도 있습니다. 어느 논문도 같은 워크로드에서 버전 관리의 위치만 바꿔 총비용을 비교하지 않았습니다. SVCC의 확장은 구현되지 않았고, Ira의 데이터베이스 적용은 스케치이며, SQL Azure의 수치는 같은 시스템 안에서 개선 기능의 효과를 잰 값입니다.
비용 위치로 고르는 기준
이 글은 동시성 제어와 복제 설계를 각 비용이 쌓이는 계층과 그 계층이 이미 병목인지로 고르자고 제안합니다. 네 논문이 제시하거나 관찰한 비용의 위치를 정리하면 다음과 같습니다.
| 비용 | 단일 엔진 | 네 논문이 제시하거나 관찰한 위치 |
|---|---|---|
| 버전 관리와 GC | 엔진 내부의 백그라운드 작업 | 엔진 안의 PVS 정리(SQL Azure), 저장 계층의 시간 기준 만료(DSQL), 주 인스턴스에서 빼고 복제본과 분석 엔진에 넘기자는 제안(SVCC) |
| 충돌 판정 | 실행 중 잠금 또는 커밋 시 검증 | 커밋 시점의 Adjudicator(DSQL), 주 인스턴스의 2PL(SVCC 제안) |
| 복제와 재실행 | 장애 복구 때의 로그 재실행 | QP가 계산한 사후 이미지를 저장 노드가 적용(DSQL), 주 복제본의 힌트로 백업 재실행 단축(Ira, Ethereum) |
이 위치를 바탕으로 상황별 후보와 대가를 정리하면 다음과 같습니다. 상황과 후보의 대응은 판단이며, 대가 열에는 각 논문이 보고하거나 인정한 비용만 적었습니다.
| 상황 | 먼저 검토할 설계 | 대가 |
|---|---|---|
| 주 인스턴스에서 쓰기와 막히지 않고 최신 스냅샷을 읽어야 함 | 주 인스턴스의 MVCC 유지 | 버전 정리 작업, 긴 트랜잭션에 묶인 정리 지연 |
| 긴 분석을 복제본이나 분석 엔진으로 보낼 수 있고 짧은 쓰기만 남음 | 주 인스턴스의 단일 버전 2PL | 고경합과 긴 트랜잭션 대응이 미검증, 범위 잠금 비용 미반영 |
| 실행 중인 트랜잭션 목록을 모으기 어려운 분산 저장 계층 | 트랜잭션 시간 상한과 시간 기준 GC | 5분 같은 상한, 대량 작업의 분할, 분석과 OLAP 용도에는 맞지 않음 |
| 문장마다 리전 사이 왕복이 끼어듦 | 커밋 시점 충돌 판정(OCC) | 충돌 시 abort와 재시도, snapshot isolation의 write skew |
| 커밋이 백업 재실행을 기다리고 재실행이 I/O에 묶임 | 주 복제본의 접근 힌트 | 주 복제본 전체 시간 증가, 잘못된 힌트로 인한 지연, 데이터베이스에서는 미측정 |
주 인스턴스가 이미 쓰기 병목이라면, 주 인스턴스에 일을 더하는 선택은 마지막에 검토하는 편이 맞습니다. MVCC 정리와 힌트 생성이 여기에 해당합니다. 이는 판단입니다.
참고 자료
- The Case for Single-Version Concurrency Control in the Cloud, arXiv:2610.15793 (2026-10, CIDR'27 채택)
- Highly Scalable SQL Azure MVCC Version Cleaner, PVLDB 19(12) (2026)
- Aurora DSQL: Scalable, Multi-Region OLTP, arXiv:2607.13276 (2026-07)
- Ira: Efficient Transaction Replay for Distributed Systems, arXiv:2601.21286 (2026-01, v3 2026-08, USENIX Security 2026 채택)
모든 수치는 2026-10 기준으로 각 원문에서 대조했습니다.
정리
2026년 논문 네 편은 버전 관리, 충돌 판정, 재실행 비용이 단일 엔진과 다른 계층에 놓이는 설계를 보여 줍니다. SVCC 논문은 버전 관리를 주 인스턴스에서 빼자고 제안했고, SQL Azure 논문은 엔진에 남은 MVCC 정리 비용을 운영 수치로 보여 주었습니다. DSQL은 충돌 판정을 커밋에 모으고 GC 시점 판단을 시간 상한으로 정했으며, Ira는 Ethereum 주-백업 복제에서 백업의 재실행 비용 일부를 주 복제본으로 옮겼습니다.
이 설계들의 대가는 트랜잭션 길이 제한, 커밋 시 abort, 저장 노드의 읽기 대기, 주 복제본의 실행 시간 증가로 나타납니다. SVCC의 처리량 비교는 짧은 TPC-C 실행에서, Ira의 재실행 단축은 Ethereum 재실행에서 측정했고, 어느 논문도 같은 워크로드의 총비용을 비교하지 않았습니다. 그래서 비용이 쌓이는 계층을 기준으로 설계를 다시 따져야 한다는 결론은 이 글의 판단이며, 설계를 바꾸기 전에 각 비용이 놓일 계층과 그 계층이 이미 병목인지부터 확인해야 합니다.