AWS CLI로 DynamoDB GSI 쿼리하기
글로벌 보조 인덱스를 쿼리하는 것은 평범한 aws dynamodb query에 플래그 하나, --index-name을 더한 것입니다. 그러면 키 조건은 테이블이 아니라 인덱스의 키를 대상으로 합니다. 여기서는 AlbumTitle-index 덕분에 앨범으로 곡을 가져올 수 있는데, 기본 테이블(Artist + SongTitle)로는 스캔 없이 처리할 수 없는 액세스 패턴입니다.
코드
aws dynamodb query \
--table-name 'Music' \
--index-name 'AlbumTitle-index' \
--key-condition-expression '#hashKey = :hashKeyValue' \
--expression-attribute-names '{"#hashKey":"AlbumTitle"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Danzon"}}'출력은 일치하는 항목들을 DynamoDB JSON으로 담습니다:
{
"Items": [
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}, ...}
],
"Count": 2,
"ScannedCount": 2
}설명
이 쿼리에 대해 기본 테이블에는 아무것도 청구되지 않습니다. --return-consumed-capacity INDEXES를 추가하면 그 구분이 명시적으로 드러납니다:
"ConsumedCapacity": {
"CapacityUnits": 132.0,
"Table": {"CapacityUnits": 0.0},
"GlobalSecondaryIndexes": {"AlbumTitle-index": {"CapacityUnits": 132.0}}
}테이블에는 0, 전부 인덱스에 붙습니다. GSI는 자체 키 스키마와 자체 파티션, 자체 용량을 가진 별도의 테이블이며, 이를 읽는 일은 기본 테이블을 건드리지 않습니다. 그래서 GSI에는 자기만의 스로틀링 사연도 있습니다. 읽기는 서로 넘어가지 않는데도 스로틀링된 GSI는 기본 테이블 쓰기를 스로틀링시킬 수 있습니다.
--consistent-read는 격하되는 게 아니라 거부됩니다. GSI는 비동기로 복제되며, 그것을 바꾸는 플래그는 없습니다:
aws: [ERROR]: An error occurred (ValidationException) when calling the Query operation: Consistent reads are not supported on global secondary indexes종료 코드는 254입니다. API 레퍼런스도 미리 같은 말을 합니다: "Strongly consistent reads are not supported on global secondary indexes. If you query a global secondary index with ConsistentRead set to true, you will receive a ValidationException"(2026-07-28 확인). 로컬 보조 인덱스는 이를 받아들이며, LSI를 고를 몇 안 되는 진짜 이유 중 하나입니다. 그 지연 자체는 GSI가 최종적 일관성인 이유에서 다룹니다.
인덱스 키가 없는 항목은 그냥 인덱스에 들어가지 않습니다. 같은 테이블에서 세어 보면 기본 테이블에는 항목이 35개, AlbumTitle-index에는 32개였습니다. 빠진 셋은 AlbumTitle 속성이 아예 없으며, attribute_not_exists(AlbumTitle) 스캔으로 확인했습니다. 오류도 경고도 없었습니다. 이것이 희소 인덱스 패턴이며, 인덱싱하고 싶은 행에만 플래그 속성을 쓸 때는 의도적인 설계이지만, 인덱스가 테이블을 그대로 반영한다고 가정하면 조용한 데이터 유실 버그가 됩니다.
인덱스가 투영한 것만 받을 수 있습니다. "If you query or scan a global secondary index, you can only request attributes that are projected into the index. Global secondary index queries cannot fetch attributes from the parent table"(2026-07-28 확인). KEYS_ONLY나 INCLUDE 인덱스에서는 나머지를 채우려고 결과마다 get-item을 한 번씩 더 하게 된다는 뜻이며, 그것이 바로 피하려던 N+1입니다. 투영은 인덱스를 만들 때 고정되고 이후에는 바꿀 수 없습니다. 고르기 전에 인덱스 투영을 보세요.
인덱스 키는 고유하지 않습니다. 여러 항목이 하나의 AlbumTitle을 공유할 수 있으므로, 같은 조건의 테이블 쿼리라면 항목 하나를 돌려줄 상황에서도 GSI 쿼리는 모음을 돌려줍니다. 바로 이 이유로 GSI에 대한 get-item 같은 것은 존재하지 않습니다.
페이지네이션은 다른 테이블 쿼리와 똑같이 동작합니다. 자동 페이지네이션된 결과에 대해 CLI가 한 페이지의 ConsumedCapacity만 보고하는 버릇까지 그렇습니다. 그 부분은 AWS CLI로 하는 Query에서 자세히 측정했고, 플래그는 여기서도 같습니다.
시각적으로 해보기
인덱스 쿼리는 테이블 쿼리보다 움직이는 부품이 많습니다. 올바른 인덱스, 인덱스 자체의 키 이름, 그리고 필요한 속성을 담지 않았을 수도 있는 투영까지요. 무료 DynamoDB Query Builder는 인덱스를 고르게 하고, 그 인덱스의 키에 맞춰 키 조건을 만들며, CLI 명령을 내놓습니다.
테이블에 실제로 어떤 인덱스가 있는지 보고 자신의 데이터에 대해 쿼리하려면 — 투영 목록, 스크롤하면 페이지가 넘어가는 그리드, 요청을 CLI 명령으로 다시 복사하기까지 — DynoTable을 다운로드하세요.
관련 예제
- Node.js에서 DynamoDB GSI 쿼리하기 — AWS SDK v3로 하는 같은 인덱스 쿼리.
- Python에서 DynamoDB GSI 쿼리하기 — boto3로 하는 같은 인덱스 쿼리.
- GSI vs. LSI — 액세스 패턴에 맞는 인덱스 유형.
- "The table does not have the specified index" — 인덱스 이름이 맞지 않는 경우(GSI 이름은 대소문자를 구분합니다).
- "Consistent reads are not supported on global secondary indexes" — GSI에서 일관된 읽기 플래그가 실패하는 이유.
참고 자료
- Query — Amazon DynamoDB API Reference
- query — AWS CLI Command Reference
- Using Global Secondary Indexes in DynamoDB — Amazon DynamoDB Developer Guide
- Using AWS CLI pagination options — AWS CLI User Guide
2026-07-28에 aws-cli/2.36.9로 포트 9000의 DynamoDB Local(amazon/dynamodb-local)에 대해, ALL을 투영하는 AlbumTitle-index가 있는 Music 테이블에서 재현했습니다. 오류 텍스트, 용량 분할, 항목 개수는 캡처한 출력입니다.