在dynamodb中扫描和查询有什么区别?什么时候使用扫描/查询?

时间:2017-04-17 13:12:52

标签: amazon-dynamodb

DynamoDb文档中指定的查询操作:

  

查询操作仅搜索主键属性值,并支持关键属性值的比较运算符子集,以优化搜索过程。

和扫描操作:

  

扫描操作扫描整个表格。您可以指定过滤器以应用于结果,以在完整扫描后优化返回给您的值。

哪种情况最好基于效果和成本考虑因素。

5 个答案:

答案 0 :(得分:25)

您将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值。 该值应仅等于operator(=)。

  • 因此,只提取与该分区键/主键值相等的项目。

  • 如果您执行扫描操作,它会获取该表中的所有项目,并在获取该数据后过滤掉数据。

注意:请勿执行超出RCU的扫描操作。

答案 1 :(得分:19)

创建Dynamodb表时,选择“主键和本地二级索引”(LSI),以便“查询”操作返回所需的项目。

查询操作仅支持对主键进行相等的运算符评估,但在排序键上有条件(=,<,< =,>,> =,Between,Begin)。

扫描操作通常较慢且较昂贵,因为操作必须遍历表中的每个项目以获取您请求的项目。

示例:

Table: CustomerId, AccountType, Country, LastPurchase

Primary Key: CustomerId + AccountType

在此示例中,您可以使用Query操作来获取:

  1. 在AccountType上带有条件过滤器的CustomerId
  2. 需要使用扫描操作返回:

    1. 具有特定AccountType的所有客户
    2. 基于国家/地区的条件过滤器的项目,即来自美国的所有客户
    3. 基于LastPurchase条件过滤器的项目,即上个月购买的所有客户
    4. 避免对常用操作进行扫描操作,创建本地二级索引(LSI)或全局二级索引(GSI)。

      示例:

      Table: CustomerId, AccountType, Country, LastPurchase
      
      Primary Key: CustomerId + AccountType
      GSI: AccountType + CustomerId
      LSI: CustomerId + LastPurchase
      

      在此示例中,Query操作可以允许您获取:

      1. 在AccountType上带有条件过滤器的CustomerId
      2. [GSI]针对特定AccountType的CustomerIds的条件过滤器
      3. [LSI]具有LastPurchase条件过滤器的CustomerId

答案 2 :(得分:6)

就性能而言,我认为为应用程序设计表格以使用Query而不是Scan是一种很好的做法。因为扫描操作总是在筛选出所需的值之前扫描整个表,这意味着处理数据操作(如读取,写入和删除)需要更多的时间和空间。有关详细信息,请参阅the official document

答案 3 :(得分:2)

查询比“扫描”要好得多-在性能上比较明智。顾名思义,scan将扫描整个表。但是您必须非常了解表键,排序键,索引和相关的排序索引,以便知道可以使用查询。 如果您使用以下方法过滤查询:

  • 键和键排序
  • 索引
  • 索引及其相关的排序键

使用查询!否则,请使用scan,它可以更灵活地选择要过滤的列。

您不能查询是否:

  • 过滤器中超过2个字段(例如键,排序和索引)
  • 仅对(主键或索引的)键进行排序
  • 常规字段(不是键,索引或排序)
  • 混合索引和排序(带有索引2的index1)\
  • ...

一个很好的解释: https://medium.com/@amos.shahar/dynamodb-query-vs-scan-sql-syntax-and-join-tables-part-1-371288a7cb8f

答案 4 :(得分:0)

与关系数据库中的类似。

query条件下使用where使用主键,由于大多数键结构是二叉树,因此计算复杂度为log(n)

scan查询期间,您必须扫描整个表,然后对每个row应用过滤器以找到正确的结果。表现为O(n)。如果您的桌子很大,它的速度要慢得多。

简而言之,如果您知道主键,请尝试使用get。仅在最坏的情况下scan

还要考虑全局二级索引,以支持对不同键的不同类型的查询,从而获得性能目标