不使用SCAN查询DynamoDB非键属性匹配记录的最优方案咨询
DynamoDB非键属性条件查询替代SCAN的最优方案
针对你需要筛选所有attribute3取值为true的记录的需求,有3种比全表SCAN成本更低的可行方案,按适用优先级排序如下:
方案1:创建以attribute3为分区键的全局二级索引(GSI)
这是最适配通用场景的方案:
- 为你的表新增一个GSI,指定
attribute3为GSI的分区键,可根据后续查询需要将原表的attribute1、attribute2设为GSI的排序键,或直接将所有需要返回的属性投射到GSI中 - 查询时直接对该GSI执行Query操作,指定分区键值为
true即可一次性拉取所有符合条件的记录,Query操作的读成本仅和匹配到的记录量相关,远低于需要扫描全表所有数据的SCAN操作,表数据量越大成本优势越明显 - 注意:如果
attribute3为true的记录占总表记录比例超过20%,该方案的成本优势会有所下降,但仍然比全表SCAN的成本更可控
方案2:使用稀疏全局二级索引(仅适用于attribute3为true的记录占比极低的场景)
如果符合条件的记录占比不足总记录的10%,可以做进一步优化:
- 写入数据时,仅当
attribute3设为true时,才新增一个固定值的专属索引属性(例如命名为idx_attr3_true,值固定为1),将该属性设为GSI的分区键 - 这种稀疏GSI只会包含所有
attribute3为true的记录,索引存储空间远小于普通GSI,查询效率更高,成本最低
方案3:新增缓存层(仅适用于查询频率高、attribute3值变更频率低的场景)
如果该查询请求的调用量很高,且attribute3的取值变更不频繁,可以将符合条件的查询结果缓存到Redis、ElastiCache等内存服务中,仅在原表数据变更时异步更新缓存,几乎可以完全规避DynamoDB的读成本。
补充说明:如果你的表总数据量很小(比如总记录数不足1万条),全表SCAN的实际成本非常低,不需要额外引入GSI增加存储和写入成本,可以直接使用带FilterExpression的SCAN操作即可,参考代码示例如下:
# Python SDK 示例 import boto3 from boto3.dynamodb.conditions import Attr dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('你的表名') response = table.scan( FilterExpression=Attr('attribute3').eq(True) ) match_items = response['Items']
内容的提问来源于stack exchange,提问作者user2427573
相关产品推荐
相关产品推荐

