用 AWS CLI 做 DynamoDB Scan
aws dynamodb scan 会自动分页,这很方便,但也意味着你用来判断损失有多大的那个唯一数字,默认就是错的。什么时候该彻底避开这个操作,见 Query vs. Scan。
代码
aws dynamodb scan \
--table-name 'Music' \
--filter-expression '#filter0 >= :filterValue0' \
--expression-attribute-names '{"#filter0":"Year"}' \
--expression-attribute-values '{":filterValue0":{"N":"2010"}}'--return-consumed-capacity 报告的是一页,不是整次扫描
数据集是 600 首歌,每首大约 3.9 KB,其中 8 首匹配。给上面那条命令加上 --return-consumed-capacity TOTAL,CLI 打印的是:
{ "Count": 8, "ScannedCount": 600, "CU": 128.5 }这次扫描真实花掉的是跨三页的 284.5 个读取单元。Count 和 ScannedCount 是三页累加的;ConsumedCapacity 却只取了第一页,其余的被丢掉了。与其说这是 bug,不如说这是一条声明好的规则——botocore 的 DynamoDB 分页器配置把 Count 和 ScannedCount 列为结果键,把 ConsumedCapacity 列为非聚合键。
破绽在于:工作量没变,这个数字却会变。同一张表、同样读了 600 个项目,只多加一个参数:
--page-size 50 -> { "Count": 8, "ScannedCount": 600, "CU": 24.0 }如果你要根据一次 CLI 扫描来给表定容量,请用 --page-size 加 --starting-token 自己把各页累加,或者从 CloudWatch 读取容量。
--max-items 并不会让扫描停下来
--max-items 3 读起来像是一次廉价的抽样。其实不是:
--max-items 3 -> { "Count": 8, "ScannedCount": 600 }CLI 会一直请求下一页,直到攒够足够的匹配项——在一个高选择性的过滤器下,这意味着整张表——然后再截断打印出来的列表。它自己的续读 token 把这一点说得明明白白:
{"ExclusiveStartKey": {"Artist": {"S": "Arturo Sandoval"},
"SongTitle": {"S": "Cubano Chant 0541"}}, "boto_truncate_amount": 3}boto_truncate_amount 是一个客户端计数器。要限制 DynamoDB 读多少,请用 --page-size,它会给每个底层请求设上 API 的 Limit,再用 --starting-token 续读:
aws dynamodb scan \
--table-name 'Music' \
--page-size 500 \
--max-items 100 \
--starting-token "$NEXT_TOKEN"2026-07-28 用 aws-cli/2.36.9 针对 DynamoDB Local(amazon/dynamodb-local)实测。上方的 JSON 是 CLI 自己的输出,只是用 --query 重新排布以适应宽度。
说明
--filter-expression是在读取之后才跑的,所以它缩小的是输出,不是账单。#filter0通过--expression-attribute-names指代Year,因为Year是保留字。--expression-attribute-values要求这个数字被引两次:JSON 外面一层 shell 引号,值本身再作为 JSON 字符串。去掉里面那层引号根本到不了 DynamoDB——CLI 会在本地就拒绝它,报Invalid type for parameter ExpressionAttributeValues.:v.N, value: 2010, type: <class 'int'>, valid types: <class 'str'>。--page-size才是会改变 API 调用的那个参数。它会变成每个底层请求上的Limit,限制每页求值的项目数。分页家族的其余成员(--max-items、--starting-token)都只是 CLI 在管理自己的输出。- 并行扫描需要给每个 worker 加
--segment N --total-segments M,而且每个 worker 各自维护自己的--starting-token。它买到的是墙上时钟时间,不是容量。
用可视化的方式来做
DynamoDB 表达式构建器会输出已经为 shell 转义好的过滤器和两个 JSON 映射,从而去掉那层让 CLI 表达式还没到 DynamoDB 就先失败的引号问题。
要在图形界面里浏览表、用带过滤和分页的网格,请下载 DynoTable,而不是从终端里盲扫。
相关指南
- Query vs. Scan——什么时候(很少)用
scan是合理的。 - 为什么我的 DynamoDB Scan 又慢又贵?——成本模型以及如何避开它。
- DynamoDB ProvisionedThroughputExceededException——全表扫描会对一张预置容量的表做些什么。
- DynamoDB ThrottlingException——另一种限流,以及指数退避如何应对它。