DynamoDB 中的 BatchGetItem 和 Query 有什么区别?

What's the difference between BatchGetItem and Query in DynamoDB?

我一直在浏览 AWS DynamoDB 文档,但我一直无法弄清楚 batchGetItem() 和 Query() 之间的核心区别是什么。两者都根据表和索引中的主键检索项目。唯一的区别在于检索到的项目的大小,但这似乎并不是一个突破性的差异。两者都支持条件更新。

在什么情况下我应该使用 batchGetItem 而不是 Query,反之亦然?

简而言之: BatchGetItem 适用于表并使用散列键来标识您要检索的项目。您最多可以在回复中获得 16MB 或 100 个项目

查询适用于表、本地二级索引和全局二级索引。您最多可以在响应中获取 1MB 的数据。最大的区别是查询支持过滤表达式,这意味着你可以请求数据,DDB 会在服务器端为你过滤。

如果你真的想使用其中任何一个,你可能可以实现同样的事情,但经验法则是当你需要从 DDB 中批量转储内容时执行 BatchGet,并在需要时查询缩小您想要检索的范围(并且您希望发电机为您过滤数据)。

根据官方文档: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#CapacityUnitCalculations

For BatchGetItem, each item in the batch is read separately, so DynamoDB first rounds up the size of each item to the next 4 KB and then calculates the total size. The result is not necessarily the same as the total size of all the items. For example, if BatchGetItem reads a 1.5 KB item and a 6.5 KB item, DynamoDB will calculate the size as 12 KB (4 KB + 8 KB), not 8 KB (1.5 KB + 6.5 KB).

For Query, all items returned are treated as a single read operation. As a result, DynamoDB computes the total size of all items and then rounds up to the next 4 KB boundary. For example, suppose your query returns 10 items whose combined size is 40.8 KB. DynamoDB rounds the item size for the operation to 44 KB. If a query returns 1500 items of 64 bytes each, the cumulative size is 96 KB.

如果您需要以比 GetItem 小的 HTTP 开销检索许多项目,您应该使用 BatchGetItem。

BatchGetItem 的成本与为每个单独的项目调用 GetItem 的成本相同。但是,它可以更快,因为您发出的网络请求更少。

其他答案中缺少一个重要的区别:

  • 查询需要 分区
  • BatchGetItems 需要

查询仅在您要获取的项目碰巧共享一个分区(散列)键时才有用,并且您必须提供此值。此外,您必须提供 exact 值;您不能对分区键进行任何部分匹配。从那里您可以为排序键指定一个附加值(可能 partial/conditional)以减少读取的数据量,并使用 FilterExpression 进一步减少输出。这很好,但它有一个很大的限制,即您无法获取位于单个分区之外的数据。

BatchGetItems 是它的反面。您可以跨多个分区(甚至跨多个表)获取数据,但是您必须知道完整和确切的主键:即分区(散列)键[=16] =]and 任何类型(范围)。这实际上就像在一次操作中多次调用 GetItem。您没有 Query 的部分搜索和过滤选项,但您也不限于单个分区。

DynamoDB 将值存储在两种类型的键中:单个键,称为 partition 键,如 "jupiter";或复合分区和 range 键,如 "jupiter"/"planetInfo""jupiter"/"moon001""jupiter"/"moon002".

A BatchGet 帮助您同时获取大量键的值。这假设您知道要获取的每个项目的完整密钥。因此,如果您只有分区键,则可以执行 BatchGet("jupiter", "satrun", "neptune"),如果您使用的是分区键 + 范围键,则可以执行 BatchGet(["jupiter","planetInfo"], ["satrun","planetInfo"], ["neptune", "planetInfo"])。每件物品独立收费,费用与个人获得相同,只是结果是批量的,调用节省了时间(不是金钱)。

A Query 另一方面,仅在分区 + 范围键组合内工作,可帮助您找到您不一定知道的项目和键。如果你想数木星的卫星,你会做 Query(select(COUNT), partitionKey: "jupiter", rangeKeyCondition: "startsWith:'moon'")。或者,如果您不想要取回卫星。 7 到 15 你会做 Query(select(ALL), partitionKey: "jupiter", rangeKeyCondition: "BETWEEN:'moon007'-'moon015'")。此处根据查询读取的数据项的大小向您收费,与有多少无关。

添加一个重要区别。 Query 支持 Consistent Reads,而 BatchGetITem 不支持。

BatchGetITem 可以通过 TableKeysAndAttributes

使用一致性读取

感谢@colmlg 提供的信息。