DynamoDB 스캔이 느리고 비용이 많이 드는 이유
Scan은 테이블의 모든 항목을 읽고 나중에 필터링만 합니다. 그것은
SQL 근육 메모리에서 도달하는 작업과 조용히 수행되는 작업
남은 RDS 상자보다 지연 시간을 더 악화시키면서 청구서를 낭비하게 됩니다.
DynamoDB 스캔이 느리고 비용이 많이 드는 이유는 무엇입니까?
A Scan은 FilterExpression가 실행되기 전에 테이블의 모든 항목을 읽습니다.
얼마나 적은 행이 반환되더라도 전체 테이블을 읽으려면 비용을 지불해야 합니다.
테이블이 커지면 속도가 느려집니다. 수정은 거의 항상 Query 키로 이루어집니다.
키 주변의 액세스 패턴을 사용하여 DynamoDB가 대신 하나의 파티션에 접근하도록 합니다.
모든 것.
-
Scan는 매번 전체 테이블을 읽습니다. 결과 개수가 아닌 크기, 지불 금액과 소요 시간을 결정합니다. FilterExpression는 비용에 대한 거짓말입니다. 읽기가 끝난 후에 실행됩니다. 측정되므로 12개 항목을 반환하면 1,200만 개를 읽는 비용이 청구될 수 있습니다.-
Scan는 성장함에 따라 속도가 느려집니다. 키가 있는Query는 평평하게 유지됩니다. 접촉합니다. 테이블 크기에 관계없이 하나의 파티션. - 수정은 거의 항상 튜닝이 아닌 모델링입니다. 일상적인 질문인데 열쇠가 없습니다.
스캔이 실제로 하는 일
SQL에서 왔기 때문에 SELECT * FROM events WHERE type = 'checkout'는 자유로워요 —
엔진에 인덱스가 있거나 없거나 둘 중 어느 쪽이든 행을 다시 가져옵니다. 에서
DynamoDB에는 이를 결정하는 쿼리 플래너가 없습니다.
Scan은 한 번에 1MB씩 전체 테이블을 순차적으로 탐색하고 각 테이블을 건네줍니다.
FilterExpression 페이지로 이동하세요. 필터가 거부하는 내용은 여전히 읽혀집니다.
여전히 측정되어 있고 청구서에 남아 있습니다. (AWS: 테이블 스캔)
그것이 바로 함정입니다. 필터는 WHERE 절처럼 보이지만
결과 집합은 비용이 아닙니다. A Scan은 다음과 같은 경우에도 동일한 읽기 용량을 소비합니다.
필터가 없습니다. (AWS: 테이블 스캔)
읽기 단위 계산
DynamoDB 미터는 (RCU)로 표시됩니다. 하나의 RCU가 단일 구매 최대 4KB의 항목 읽기; 읽음 비용은 절반입니다. 더 큰 항목은 다음 4KB로 반올림됩니다. (AWS: 읽기/쓰기 용량 모드)
분석표 ProductEvents를 선택하세요. 각 행은 하나의 추적된 이벤트입니다.
PK = "TENANT#acme"
SK = "TS#2026-06-23T14:08:55Z#evt_9f3a"
attrs: eventType, sessionId, userId, payloadBytes하나의 바쁜 테넌트 아래에서 각각 ~1KB의 2,000,000 이벤트를 보유한다고 가정해 보겠습니다. 당신 오늘 결제를 원해요. 반사적 움직임:
Scan ProductEvents
FilterExpression: eventType = "checkout"
해당 필터는 40개의 행을 반환할 수 있습니다. 하지만 Scan는 2,000,000개의 항목을 모두 읽었습니다.
먼저. 각각 ~1KB(4KB당 1RCU, 최종적으로는 4KB당 0.5RCU로 일관됨)
대략 250,000개의 RCU를 측정하고 ~2GB의 데이터를 페이징하여
40개의 아이템을 돌려주세요.
이제 액세스 패턴을 키로 모델링하고 대신 이를 모델링합니다.
Query ProductEvents
PK = "TENANT#acme"
AND SK begins_with "TS#2026-06-23"
이는 한 파티션의 일치하는 슬라이스만 읽습니다. 40개의 결제 행이 있는 경우 게다가 그날의 다른 이벤트는 최대 2MB에 달하므로 읽기 비용은 최대 2MB입니다. 2GB. 동일한 답변, 비용의 극히 일부 — 지연 시간은 일정하게 유지됩니다. 테이블이 커지면서.
스캔 대 쿼리, 측정
| 스캔 + 필터 | 키 입력 쿼리 | |
|---|---|---|
| 읽기 | 테이블의 모든 항목 | SK로 좁혀진 파티션 1개 |
| 청구 용량 | 필터 전의 전체 테이블 | 슬라이스의 항목만 |
| 우리의 예 | ~250,000 RCU(~2GB) | 수백 개의 RCU(~2MB) |
| 대기 시간 | 테이블 크기에 따라 증가 | 테이블이 커짐에 따라 평평해짐 |
| 결과 개수 | 비용에 대해 아무것도 결정하지 않음 | 귀하가 지불하는 금액과 일치 |
표에 인코딩된 레슨: Scan에서는 결과 수와 청구서가 다음과 같이 표시됩니다.
관련이 없습니다. Query에서는 서로를 추적합니다.
스캔하기 전에 결정하세요
대부분의 우연한 질문은 하나의 질문에서 비롯됩니다: 파티션 이름을 지정할 수 있습니까?
필요합니까? 그렇다면 Query입니다. 그렇지 않은 경우 수정은 더 큰 필터가 아니라 핵심입니다.
다음은 흐름 형식의 결정입니다.
경로는 거의 항상 Query에서 끝납니다. 그렇지 않은 경우에만 Scan로 넘어갑니다.
키 - 존재하거나 추가 가능 - 액세스 패턴에 적합합니다.
패턴이 실제적이고 반복적이지만 기본 테이블에서 해당 패턴에 키를 지정할 수 없는 경우
Global Secondary Index를 추가하라는 신호이므로 질문은
Query가 됩니다. 액세스 패턴을 중심으로 키를 모델링하는 것은 사전에
전체 게임 — single-table design을 참조하세요.
필터가 아닌 키 입력 쿼리를 작성합니다.
키 이상의 조건이 필요한 경우에는 키를 사용하지 않고 의도적으로 빌드하세요.
모든 것을 FilterExpression에 버리세요. 는
DynamoDB Expression Builder은 다음을 생성합니다.
KeyConditionExpression 및 속성 자리 표시자가 있으므로 파티션이
및 정렬 키는 DynamoDB가 읽기를 측정하기 전이 아니라 읽기를 측정하기 전에 범위를 좁힙니다.
KeyConditionExpression: PK = :tenant AND begins_with(SK, :day)
스캔이 실제로 괜찮은 경우
Scan은 일상적인 쿼리에 대한 잘못된 기본값입니다. 이럴 때 딱 맞는 도구가 바로
당신은 정말로 "모든 것을 읽으십시오"를 의미합니다.
- 일회성 내보내기 또는 백필이 수동으로 실행됩니다.
- 전체 테이블이 몇 KB에 불과한 작은 구성/조회 테이블.
- 의도적으로 전체 테이블을 페이지로 표시하는 백그라운드 작업. 그것들을 나누어 라.
Segment/TotalSegments— a — 대신에 한 번의 긴 순차 크롤링. (AWS: 테이블 스캔)
그리고 PartiQL도 여러분을 구해 주지 않습니다. 키 조건절이 없는
SELECT * FROM ProductEvents WHERE eventType = 'checkout'은 곧장 Scan으로 컴파일됩니다.
SQL 옷을 입은 같은 자충수입니다. (전체 분석은
Query vs Scan을 보세요.)
교차 항목 분석이 정말로 필요한 경우 — GROUP BY, JOIN, 집계
DynamoDB는 표현할 수 없습니다. DynoTable의 SQL Workbench는 이를 클라이언트 측에서 실행합니다.
전체 Scan로 테이블을 망치는 대신 제한된 결과 집합을 사용합니다.
다음 단계
두 패턴의 비용을 추정해 보세요. pricing calculator, 읽다 API 수준 대비의 경우 Query vs Scan, download DynoTable 이를 자신의 테이블과 비교하여 실행하고 시청하세요. 각 접근 방식이 실제로 읽는 항목 수입니다.