我一直在浏览AWS DynamoDB文档,并且在我的生命中,无法弄清楚batchGetItem()和Query()之间的核心区别是什么。两者都根据表和索引中的主键检索项目。唯一的区别在于所检索项目的大小,但这看起来并不像是一个突破性的差异。两者都支持条件更新。
在什么情况下我应该使用batchGetItem而不是Query?反之亦然?
答案 0 :(得分:27)
对于BatchGetItem,批处理中的每个项目都是单独读取的,因此DynamoDB首先将每个项目的大小向下舍入到下一个4 KB,然后计算总大小。结果不一定与所有项目的总大小相同。例如,如果BatchGetItem读取1.5 KB项目和6.5 KB项目,DynamoDB将计算大小为12 KB(4 KB + 8 KB),而不是8 KB(1.5 KB + 6.5 KB)。
对于Query,返回的所有项目都被视为单个读取操作。因此,DynamoDB计算所有项目的总大小,然后向上舍入到下一个4 KB边界。例如,假设您的查询返回10个项目,其组合大小为40.8 KB。 DynamoDB将操作的项目大小舍入为44 KB。如果查询返回1500个项目,每个64字节,则累积大小为96 KB。
所以,只有当你的项目都相对较大时才应该使用BatchGetItem(因此4KB的总结会产生很小的影响),并且你需要在一次调用中检索> 1MB。
在任何其他情况下,请使用查询,否则您最终会被收取更多费用;)
答案 1 :(得分:15)
简而言之: BatchGetItem适用于表,并使用哈希键来标识要检索的项。您可以在响应中获得最多16MB或100个项目
查询适用于表,本地二级索引和全局二级索引。您可以在响应中获得最多1MB的数据。最大的区别是查询支持过滤表达式,这意味着您可以请求数据,DDB将为您过滤服务器端。
如果您想要使用其中任何一个,您可能可以实现相同的目标,但是当您需要从DDB批量转储内容并在需要缩小时查询时,您可以执行BatchGet你需要检索什么(并且你希望发电机为你重复过滤数据)。
答案 2 :(得分:2)
DynamoDB将值存储在两种键中:一个键,称为 partition 键,例如"jupiter"
;或复合分区和 range 键,例如"jupiter"/"planetInfo"
,"jupiter"/"moon001"
和"jupiter"/"moon002"
。
BatchGet
可帮助您同时获取大量键的值。假设您知道要获取的每个项目的完整密钥。因此,如果只有分区键,则可以执行BatchGet("jupiter", "satrun", "neptune")
;如果使用分区+范围键,则可以执行BatchGet(["jupiter","planetInfo"], ["satrun","planetInfo"], ["neptune", "planetInfo"])
。每个项目都是独立收取的,费用与个人收取的费用相同,只是将结果分批处理,通话可以节省时间(而不是金钱)。
另一方面,Query
仅在分区+范围键组合内有效,并可以帮助您查找不必要的项目和键。如果您想计算木星的卫星,可以做一个Query(select(COUNT), partitionKey: "jupiter", rangeKeyCondition: "startsWith:'moon'")
。或者,如果您不想获取卫星。 7到15,您将Query(select(ALL), partitionKey: "jupiter", rangeKeyCondition: "BETWEEN:'moon007'-'moon015'")
。在这里,根据查询读取的数据项的大小向您收费,而不管有多少项。
答案 3 :(得分:1)
添加一个重要的区别。 Query
支持 Consistent Reads,而 BatchGetITem
不支持。
BatchGetITem
可以通过 TableKeysAndAttributes
感谢@colmlg 提供的信息。
答案 4 :(得分:0)
其他答案中缺少一个重要的区别:
查询仅在您要获取的项目碰巧共享一个分区(哈希)键且必须提供此值时才有用。此外,您必须提供 exact 值;您不能对分区键进行任何部分匹配。在这里,您可以为sort键指定一个附加(可能是部分/条件)值,以减少读取的数据量,并通过FilterExpression进一步减少输出。这很好,但是它有一个很大的局限性,即您无法获取驻留在单个分区之外的数据。
BatchGetItems是它的反面。您可以跨多个分区(甚至跨多个表)获取数据,但必须知道 full 和确切的主键:即分区(哈希)键和任何类型(范围)。从字面上看,就像在一个操作中多次调用GetItem。您没有Query的部分搜索和过滤选项,但也不限于单个分区。