AWS CLI로 하는 DynamoDB Query
aws dynamodb query는 파티션 하나를 읽으며, 필요하면 정렬 키로 범위를 좁힙니다(Query vs Scan에서 그것이 옳은 선택인 시점을, 키 조건 표현식에서 사용 가능한 모든 연산자를 다룹니다). CLI가 그 위에 얹는 것은 자체 페이지네이션 계층이며, 이 명령에서 벌어지는 놀람 대부분의 출처입니다.
코드
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)' \
--expression-attribute-names '{"#hashKey":"Artist","#rangeKey":"SongTitle"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"},":rangeKeyValue":{"S":"C"}}'#hashKey/#rangeKey 별칭은 --expression-attribute-names를 통해 Artist/SongTitle로 풀리며, 이것이 예약어가 명령을 깨뜨리지 못하게 막아 줍니다. 정렬 키 내림차순이 필요하면 --no-scan-index-forward를 추가하세요. 기본값은 오름차순입니다.
페이지네이션
기본적으로 CLI는 자동으로 페이지를 넘깁니다 — 내부에서 LastEvaluatedKey를 따라가며 합쳐진 결과를 출력합니다. 수동으로 페이지를 넘기려면(예: 결과 집합이 클 때) 다음으로 제어하세요:
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue' \
--expression-attribute-names '{"#hashKey":"Artist"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"}}' \
--page-size 100 \
--max-items 50
# The output includes a "NextToken"; pass it back with --starting-token to continue.설명
CLI는 페이지네이션을 감추며, 비용 수치에서도 그렇습니다. 약 60 KB짜리 항목 30개, 약 1.8 MB라서 서비스 페이지가 둘인 파티션을 만들어 두고, 같은 쿼리를 --return-consumed-capacity TOTAL과 함께 세 가지 방식으로 실행했습니다:
default (auto-paginate) Count: 30 CapacityUnits: 132.0 LastEvaluatedKey: null
--no-paginate Count: 18 CapacityUnits: 132.0 LastEvaluatedKey: {…S017}
--max-items 3 Count: 18 items printed: 3 NextToken: eyJFeGNsdXNpdmVTdGFydEtleSI6…손으로 페이지를 넘겨 보면 진짜 비용이 드러납니다. 1페이지는 18개 항목에 132.0 단위, 2페이지는 12개에 88.0이었으므로 이 쿼리가 실제로 소비한 것은 220.0 읽기 단위입니다. 자동 페이지네이션 실행은 두 호출을 모두 하고 30개를 모두 돌려주면서 132.0을 보고했습니다. CLI는 페이지에 걸쳐 Items와 Count는 병합하지만 ConsumedCapacity는 병합하지 않으므로, 출력된 숫자는 이 쿼리를 40% 과소평가합니다. CLI 출력으로 용량을 산정하고 있다면 수동으로 페이지를 넘기세요. 그러지 않으면 한 페이지 기준으로 산정하게 됩니다.
--max-items는 출력 제한입니다. Limit이 아닙니다. 위 세 번째 실행은 항목 세 개를 출력하면서도 Count: 18과 ScannedCount: 18을 보고했습니다. 잘라낸 서비스 페이지가 18개 항목, 대략 1 MB였기 때문입니다. 그 전부에 대해 비용을 냈습니다. 읽기를 실제로 제한하는 DynamoDB 파라미터는 Limit이며, CLI는 그것을 --page-size로 노출합니다.
그래서 두 플래그는 서로 무관한 일을 합니다. --page-size는 API의 Limit이 되어 각 서비스 호출이 읽는 양을 바꾸고, --max-items는 병합된 결과 중 얼마만큼이 터미널에 닿을지만 정하며 나머지를 위해 NextToken을 내놓습니다. 그 토큰은 DynamoDB의 LastEvaluatedKey가 아니라 CLI 자체 장부의 base64 덩어리이며, --starting-token으로 다시 들어갑니다.
--limit도 --exclusive-start-key도 없습니다. 2.36.9에서 aws dynamodb query help를 확인해 보면 개요에 둘 다 나오지 않습니다. CLI는 DynamoDB의 페이지네이션 파라미터 둘을 없애고 자체 파라미터 셋을 대신 넣습니다. 그래서 한 호출에서 LastEvaluatedKey를 받아 다음 호출에 먹이는 자연스러운 루프는 먹일 플래그가 없습니다. 원시 API로 돌아가는 길은 요청을 그대로 받는 --cli-input-json입니다:
--cli-input-json with "Limit": 5 and an "ExclusiveStartKey"
→ Count: 5 CapacityUnits: 37.0 LastEvaluatedKey: {"Artist":…,"SongTitle":"S007"}이것이 페이지네이터도 함께 껐다는 점에 주의하세요. --no-paginate 없이도 실행은 한 페이지와 진짜 LastEvaluatedKey를 돌려주었습니다. 큰 파티션 위에 셸 루프를 작성한다면 --cli-input-json이 정직한 형태이고, --no-paginate가 빠른 형태입니다.
--query는 돈을 다 쓴 뒤에 실행됩니다. 전역 --query 플래그는 여러분의 셸에서 응답에 적용되는 JMESPath입니다. Items[?Year > '2010'] 같은 JMESPath 표현식은 필터처럼 보이지만 필터가 아닙니다. JMESPath가 보기 전에 모든 항목을 읽고, 전송하고, 청구했습니다. --filter-expression은 적어도 데이터 전송은 막지만, AWS는 그것이 "is applied after the items have already been read; the process of filtering does not consume any additional read capacity units"라고 명시합니다(2026-07-28 확인). 그 말은 양쪽으로 통합니다. 필터가 읽기 단위를 줄여 주지도 않는다는 뜻이니까요. 덜 읽는 유일한 방법은 더 좁은 키 조건이나 인덱스입니다.
요청한 것과 무관하게 한 페이지는 1 MB입니다. "A single Query operation will read up to the maximum number of items set (if using the Limit parameter) or a maximum of 1 MB of data"(2026-07-28 확인). 그보다 넓은 파티션은 언제나 페이지가 나뉘며, 그래서 위의 30개 항목 쿼리는 결코 한 번의 호출이 아니었습니다.
인덱스를 쿼리하려면 플래그 하나가 더 필요합니다. --index-name은 키 조건을 그 인덱스의 키로 바꿉니다. 글로벌 보조 인덱스는 --consistent-read도 거부합니다. AWS CLI로 GSI 쿼리하기를 참고하세요.
시각적으로 해보기
키 조건, 두 개의 플레이스홀더 맵, 그리고 페이지네이션 루프를 한 명령 안에서 제대로 맞추는 것이 여기서의 어려움 전부입니다. 무료 DynamoDB Query Builder가 인덱스와 페이징을 포함해 요청을 구성하고, 실행 가능한 CLI 명령으로 내보냅니다.
여러분의 테이블에 쿼리를 실행하려면 — 키 조건 폼, 스크롤하면 페이지를 넘기는 그리드, 요청을 다시 CLI 명령으로 복사 — DynoTable을 다운로드하세요.
관련 가이드
- Query vs. Scan —
query가 옳은 기본값인 이유. - 페이지네이션 —
LastEvaluatedKey,ExclusiveStartKey, 그리고Limit이 페이지 크기가 아닌 이유. - "Query condition missed key schema element" — 키 조건이 엉뚱한 속성을 지목했거나 파티션 키를 빠뜨린 경우.
- "Query key condition not supported" — contains나 두 번째 정렬 키 조건처럼 키 조건이 쓸 수 없는 연산자.
참고 자료
- Query — Amazon DynamoDB API Reference
- query — AWS CLI Command Reference
- Using the pagination options in the AWS CLI — AWS CLI User Guide
- Filtering AWS CLI output — AWS CLI User Guide
- Querying tables — Amazon DynamoDB Developer Guide
2026-07-28에 aws-cli/2.36.9로 포트 9000의 DynamoDB Local(amazon/dynamodb-local)을 상대로, 약 60 KB짜리 항목 30개로 이루어진 파티션에서 측정했습니다. 위의 개수, 토큰, 용량 수치는 그대로 옮긴 출력입니다. DynamoDB Local은 문서화된 반올림 규칙으로 용량을 계산합니다. 절대 수치는 형태를 보여 주는 예시로 받아들이고, 용량을 산정하기 전에 실제 서비스에서 여러분의 테이블을 직접 측정하세요.