用 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}}
}表上是零,全部落在索引上。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) 的扫描确认过。没有报错,也没有任何警告。这就是稀疏索引模式:当你只为想被索引的那些行写入标记属性时,它是有意为之的设计;而当你以为索引会镜像整张表时,它是一个静默的数据丢失 bug。
你只能拿到索引投影出来的东西。"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 与 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 针对 DynamoDB Local(amazon/dynamodb-local,端口 9000)复现,表为 Music,带一个投影 ALL 的 AlbumTitle-index。上方的错误文本、容量拆分和项目计数都是捕获到的输出。