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

我一直在浏览 AWS DynamoDB 文档,无论如何也找不出 batchGetItem ()和 Query ()之间的核心区别。两者都基于表和索引中的主键检索项。唯一的区别在于取回物品的大小,但这似乎并不是一个突破性的差异。两者都支持条件更新。

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

53603 次浏览

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

查询对表、本地辅助索引和全局辅助索引起作用。在一个响应中最多可以获得1MB 的数据。最大的区别是查询支持筛选表达式,这意味着您可以请求数据,DDB 将在服务器端为您筛选数据。

如果你真的想使用这些东西,你可能也可以达到同样的效果,但经验法则是,当你需要批量从 DDB 转储东西时,你可以使用 BatchGet,当你需要缩小你想要检索的内容时,你可以查询(并且你需要发电机为你做繁重的数据过滤)。

根据官方文件: Http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workingwithtables.html#capacityunitcalculations

对于 BatchGetItem,将分别读取批处理中的每个项,因此 DynamoDB 首先将每个项的大小四舍五入到下一个4KB,然后计算总大小。结果不一定与所有项目的总大小相同。例如,如果 BatchGetItem 读取一个1.5 KB 的项和一个6.5 KB 的项,DynamoDB 将计算其大小为12 KB (4 KB + 8 KB) ,而不是8 KB (1.5 KB + 6.5 KB)。

对于 Query,所有返回的项都被视为单个读操作。因此,DynamoDB 计算所有项的总大小,然后四舍五入到下一个4KB 边界。例如,假设您的查询返回10个合并大小为40.8 KB 的项。DynamoDB 将操作的项大小四舍五入到44KB。如果查询返回1500个项,每个项为64字节,则累计大小为96 KB。

如果与 GetItem 相比,需要检索许多 HTTP 开销较小的项,则应使用 BatchGetItem。

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

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

  • 查询需要 分区
  • BatchGetItems 需要 初选密钥

查询只有在希望获取的项共享分区(散列)键时才有用,并且必须提供此值。此外,必须提供 一模一样值; 不能对分区键进行任何部分匹配。然后,您可以为排序键指定一个附加值(可能是部分/条件值) ,以减少数据读取的数量,并使用 FilterExpression 进一步减少输出。这非常好,但是它有一个很大的限制,那就是您不能获取位于单个分区之外的数据。

BatchGetItems 是这个问题的另一面。您可以跨多个分区(甚至跨多个表)获取数据,但是您必须知道 满了和确切的主键: 即分区(散列)键 还有的任意排序(范围)。这实际上就像在一个操作中多次调用 GetItem。没有 Query 的部分搜索和过滤选项,但是也不限于单个分区。

DynamoDB 将值存储在两种类型的键中: 单个键,称为 分区键,如 "jupiter"; 或复合分区和 射程键,如 "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'")。在这里,您将根据查询读取的数据项的大小收取费用,而不管这些数据项有多少。

增加一个重要的区别。 Query支持 一致阅读,而 BatchGetITem不支持。

通过 TableKeysAndAttributes可以使用一致的读数

谢谢@colmlg 提供信息。