【发布时间】:2021-08-30 13:20:26
【问题描述】:
DynamoDb 文档中指定的查询操作:
查询操作仅搜索主键属性值,并支持键属性值的比较运算符子集以优化搜索过程。
以及扫描操作:
扫描操作扫描整个表。您可以指定过滤器以应用于结果,以在完成扫描后细化返回给您的值。
根据性能和成本考虑,哪个最好。
【问题讨论】:
标签: amazon-web-services amazon-dynamodb
DynamoDb 文档中指定的查询操作:
查询操作仅搜索主键属性值,并支持键属性值的比较运算符子集以优化搜索过程。
以及扫描操作:
扫描操作扫描整个表。您可以指定过滤器以应用于结果,以在完成扫描后细化返回给您的值。
根据性能和成本考虑,哪个最好。
【问题讨论】:
标签: amazon-web-services amazon-dynamodb
在创建 Dynamodb 表时选择主键和本地二级索引 (LSI),以便查询操作返回您想要的项目。
查询操作仅支持对主键进行相等运算符评估,但对排序键有条件(=、、>=、Between、Begin)。
扫描操作通常更慢且成本更高,因为该操作必须遍历表中的每个项目以获取您请求的项目。
例子:
Table: CustomerId, AccountType, Country, LastPurchase
Primary Key: CustomerId + AccountType
在本例中,您可以使用 Query 操作来获取:
需要使用扫描操作返回:
为避免对频繁使用的操作进行扫描操作,请创建本地二级索引 (LSI) 或全局二级索引 (GSI)。
例子:
Table: CustomerId, AccountType, Country, LastPurchase
Primary Key: CustomerId + AccountType
GSI: AccountType + CustomerId
LSI: CustomerId + LastPurchase
在这个例子中,一个查询操作可以让你得到:
【讨论】:
您的 dynamodb 表分区键/主键为 customer_country。如果使用查询,customer_country 是进行查询操作的必填字段。所有的过滤器都只能是属于customer_country的项目。
如果您执行表扫描,将对所有分区键/主键执行过滤器。首先它获取所有数据并在从表中获取后应用过滤器。
这里customer_country是分区键/主键
id 是 sort_key
-----------------------------------
customer_country | name | id
-----------------------------------
VV | Tom | 1
VV | Jack | 2
VV | Mary | 4
BB | Nancy | 5
BB | Lom | 6
BB | XX | 7
CC | YY | 8
CC | ZZ | 9
------------------------------------
如果您执行查询操作,它仅适用于 customer_country 值。
该值只能是等号运算符 (=)。
因此,只有等于该分区键/主键值的项目才会被提取。
如果您执行扫描操作,它会获取该表中的所有项目并在获取该数据后过滤掉数据。
注意:不要执行超出 RCU 的扫描操作。
【讨论】:
customer_country is the partition key/primary key 本身就是一个错误的陈述。在查看列中的重复值后,我认为它不是主键 - customer_country。
类似于关系数据库。
获取query你在where条件下使用主键,计算复杂度为log(n),因为大多数键结构是二叉树。
scan 查询时,您必须扫描整个表,然后对每个 row 应用过滤器以找到正确的结果。表演是O(n)。如果你的桌子很大,它会慢得多。
简而言之,如果您知道主键,请尝试使用query。仅scan 仅用于最坏的情况。
另外,考虑全局二级索引以支持对不同键的不同类型查询以获得性能目标
【讨论】:
就性能而言,我认为为应用程序设计表以使用Query 而不是Scan 是一种很好的做法。因为扫描操作总是在过滤出所需值之前扫描整个表,这意味着处理读取、写入和删除等数据操作需要更多的时间和空间。更多信息请参考the official document
【讨论】:
查询比扫描好得多 - 性能方面。 scan,顾名思义,将扫描整个表。但是你必须很清楚表键、排序键、索引以及相关的排序索引,才能知道你可以使用Query。 如果您使用以下方式过滤查询:
使用查询!否则使用 scan 可以更灵活地过滤哪些列。
你不能查询:
【讨论】: