AWS CLI で DynamoDB の GSI をクエリする
グローバルセカンダリインデックス のクエリは、普通の aws dynamodb query にフラグを 1 つ足したものです。--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}}
}テーブルに対してはゼロ、すべてはインデックスに対して。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 を選ぶ数少ない実質的な理由の 1 つです。遅延そのものはGSI が結果整合性である理由で扱っています。
インデックスキーを持たないアイテムは、単にインデックスに存在しません。同じテーブルで数えたところ、ベーステーブルが 35 アイテム、AlbumTitle-index が 32 でした。欠けている 3 件は 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 のインデックスでは、残りを埋めるために結果 1 件につき 2 回目の get-item が必要になり、それこそ避けようとしていた N+1 です。射影はインデックス作成時に固定され、後から変更できません。選ぶ前にインデックスの射影を参照してください。
インデックスキーは一意ではありません。多数のアイテムが 1 つの AlbumTitle を共有し得るので、GSI のクエリは、同等のテーブルクエリなら 1 件を返すところで集合を返します。GSI に対する get-item というものが存在しないのは、まさにこの理由からです。
ページネーションは、どのテーブルクエリでもそうであるように振る舞います。自動ページネーションされた結果に対して 1 ページ分の ConsumedCapacity を報告する CLI の癖も含めてです。それは AWS CLI での Query で詳しく計測しています。フラグはここでも同じです。
ビジュアルに行う
インデックスのクエリは、テーブルのクエリより動く部品が多くなります。正しいインデックス、そのインデックス自身のキー名、そして必要な属性を運んでいないかもしれない射影です。無料の DynamoDB Query Builder はインデックスを選ばせ、そのキーに対してキー条件を組み立て、CLI コマンドを出力します。
テーブルが実際にどのインデックスを持っているかを見て、自分のデータに対してクエリするには — 射影の一覧、スクロールに合わせてページングするグリッド、リクエストの CLI コマンドとしてのコピー — DynoTable をダウンロードしてください。
関連する例
- Node.js で DynamoDB の GSI をクエリする — AWS SDK v3 による同じインデックスクエリ。
- Python で DynamoDB の GSI をクエリする — boto3 による同じインデックスクエリ。
- GSI と 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 で、ALL を射影する AlbumTitle-index を持つ Music テーブルに対し、ポート 9000 の DynamoDB Local(amazon/dynamodb-local)で再現しました。エラーテキスト、キャパシティの内訳、アイテム数は取得した出力です。