DynamoDB扫描与查询(使用GSI的整个表的分区键相同)的费用进行过滤

时间:2020-08-11 10:24:59

标签: amazon-web-services amazon-dynamodb dynamodb-queries amazon-dynamodb-index

我有一个DynamoDB表,如下所示:

[id] [datetime] [name] [reasonForVisit] [__typename]

[id]是表的简单主键

[__typename]是表中所有项目的值均相同的属性

桌子已经很大。我希望能够按范围 datetime过滤数据。我的脑海中有2个可快速实施的选项,但是不确定在成本方面是否会有很大的不同。

  1. 扫描整个表,然后按日期时间过滤(因为dynamodb不允许在扫描前进行过滤)
  2. 通过固定的__typename分区创建GSI(partitionKey:__typename,sortKey:datetime)和QUERY,并按datetime排序键进行过滤,例如在10/8/10和10/11/10之间。

所以,我的问题是,由于我的分区键对于每一项都是相同的,因此是一个大分区,所以我不确定在使用过滤器查询时是否仍会导致读取整个表(类似于扫描)还是知道要根据过滤条件有效地从某项内容开始阅读?

1 个答案:

答案 0 :(得分:0)

过滤器总是after进行所有读取操作。在这种情况下,“扫描”和“查询”之间没有区别。另外,如果为所有元素创建具有相同PK的GSI,则可能会遇到“ hot partition”问题,此外,您还会slow down进行写操作。

如果您要在表中查找80%的记录,那么使用scan + filter解决方案可能会很合适。否则,您需要利用Dynamo提供的查询功能(因此通过PK和SK进行查询)。您可以做的是引入第二条记录,例如:

id(PK), datetime, name, reasonForVisit, __typename
date(PK), time(SK), id

或:

id(PK), datetime, name, reasonForVisit, __typename
date(PK), time(SK), id_list

或者如果您的数据是不可变的(历史数据)并且永远不会更改,那么:

id(PK), datetime, name, reasonForVisit, __typename
date(PK), time(SK), id, name, reasonForVisit, __typename

使用BatchGetItem完成给定范围的查询。在第一个和第二个选项中,当使用BatchWriteItem添加新记录时(如果严格一致性很重要,则为TransactWriteItem)需要两次写入。对于第三个选项,您可以改为在id上使用GSI。