说我将“名称”作为主键,将“时间戳”作为我的排序键。我意识到我可以同时使用Attr(“ timestamp”)和Key(“ timestamp”)进行查询。
我还可以使用filterexpression(Attr(“ account”)。eq(“ john”))进行表扫描,并通过udding keyconditionexpression = Key(“ account”)。eq(“ john”)进行查询,这给了我结果相同。
所以我有两个问题。通常,如果我具有相同的条件,那么使用扫描或查询会有所不同吗?在进行查询时,具有与任何其他数字属性不同的排序键的重要性是什么?
虽然带有Scan
的FilterExpression
和带有Query
的KeyConditionExpression
都可能返回相同的结果,但是这样做的方式,性能和成本都有很大的不同。在您的情况下,强烈建议您使用Query
,而不是Scan
。让我解释一下:
A Scan
始终扫描整个表。它可能会根据FilterExpression
过滤掉某些内容,但DynamoDB仍然需要读取all表中的项目,您需要为读取的数据付费。用非常有选择性的FilterExpression
(仅返回表的一小部分)进行扫描几乎总是一个坏主意。相对于您要读取的数据量而言,这将非常慢,并且会花费很多钱。
另一方面,Query
可以有效直接跳到您要的分区(KeyConditionExpression
只能指定一个分区键),然后在该分区内读取only您在KeyConditionExpression
中指定的排序键范围。执行此操作所需的时间以及对您的成本将仅与您实际读取的项目数量成正比-即使这些项目只是整个表格的一小部分。
Query
可以有效地执行此操作,因为DynamoDB分区键和排序键的工作方式:分区键也称为“哈希键”,因为它允许DynamoDB像哈希表中一样高效地查找特定分区,而无需扫描整个表格。然后,在[[inside一个分区中,按排序键对项目进行排序,因此要找到连续范围的排序键(如KeyConditionExpression
允许指定),DynamoDB无需扫描分区中的所有项目-它可以在O(logN)中有效地找到请求的范围。