Query 与 Scan
避免全表 Scan;分页 LastEvaluatedKey。
30 分钟
Query 与 Scan
Query 按主键或 GSI 键高效读取;Scan 全表遍历,成本高、应尽量避免。DynamoDB 没有 SQL 式任意 WHERE。
学习目标
- 掌握 Query 的 KeyCondition 与 FilterExpression
- 理解分页
LastEvaluatedKey与Limit - 知道何时 Scan 可接受、如何控成本
核心内容
Query(推荐)
aws dynamodb query \
--table-name UserProgress \
--key-condition-expression "PK = :pk AND begins_with(SK, :prefix)" \
--expression-attribute-values '{
":pk": {"S": "USER#u_1001"},
":prefix": {"S": "LESSON#"}
}' \
--scan-index-forward false \
--limit 10
| 参数 | 作用 |
|---|---|
| KeyConditionExpression | 必填,仅主键/GSI 键条件 |
| FilterExpression | 可选,键条件后再过滤非键属性 |
| ScanIndexForward | false = SK 降序 |
| ExclusiveStartKey | 分页起点(上一页 LastEvaluatedKey) |
Java Query 分页
QueryRequest req = QueryRequest.builder()
.tableName("UserProgress")
.keyConditionExpression("PK = :pk")
.expressionAttributeValues(Map.of(
":pk", AttributeValue.builder().s("USER#u_1001").build()))
.limit(20)
.build();
QueryResponse resp = client.query(req);
// 若 resp.lastEvaluatedKey() 非空,放入 exclusiveStartKey 继续
Scan(慎用)
aws dynamodb scan \
--table-name UserProgress \
--filter-expression "#a = :complete" \
--expression-attribute-names '{"#a":"action"}' \
--expression-attribute-values '{":complete":{"S":"complete"}}'
Scan 读 每一分区每一 Item,再应用 Filter——大表极贵。报表/analytics 导出到 S3 + Athena,或同步到 postgresql-essentials 只读副本。
与 MongoDB / SQL 对照
| 操作 | DynamoDB | MongoDB | MySQL |
|---|---|---|---|
| 主键查 | GetItem | findOne({_id}) | PK lookup |
| 索引范围 | Query + GSI | find({field}) | WHERE + INDEX |
| 全表 | Scan(贵) |