【问题标题】:What is the difference between scan and query in dynamodb? When use scan / query?dynamodb 中的 scan 和 query 有什么区别?什么时候使用扫描/查询?
【发布时间】:2021-08-30 13:20:26
【问题描述】:

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

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

以及扫描操作:

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

根据性能和成本考虑,哪个最好。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb


    【解决方案1】:

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

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

    扫描操作通常更慢且成本更高,因为该操作必须遍历表中的每个项目以获取您请求的项目。

    例子:

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

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

    1. 在 AccountType 上带有条件过滤器的 CustomerId

    需要使用扫描操作返回:

    1. 具有特定 AccountType 的所有客户
    2. 基于国家条件过滤器的项目,即来自美国的所有客户
    3. 基于 LastPurchase 条件过滤器的项目,即上个月购买的所有客户

    为避免对频繁使用的操作进行扫描操作,请创建本地二级索引 (LSI) 或全局二级索引 (GSI)。

    例子:

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

    在这个例子中,一个查询操作可以让你得到:

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

    【讨论】:

    【解决方案2】:

    您的 dynamodb 表分区键/主键为 customer_country。如果使用查询,customer_country 是进行查询操作的必填字段。所有的过滤器都只能是属于customer_country的项目。

    如果您执行表扫描,将对所有分区键/主键执行过滤器。首先它获取所有数据并在从表中获取后应用过滤器。

    例如:

    这里customer_country分区键/主键 idsort_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
    【解决方案3】:

    类似于关系数据库。

    获取query你在where条件下使用主键,计算复杂度为log(n),因为大多数键结构是二叉树。

    scan 查询时,您必须扫描整个表,然后对每个 row 应用过滤器以找到正确的结果。表演是O(n)。如果你的桌子很大,它会慢得多。

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        查询比扫描好得多 - 性能方面。 scan,顾名思义,将扫描整个表。但是你必须很清楚表键、排序键、索引以及相关的排序索引,才能知道你可以使用Query。 如果您使用以下方式过滤查询:

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

        使用查询!否则使用 scan 可以更灵活地过滤哪些列。

        你不能查询:

        • 过滤器中超过 2 个字段(例如键、排序和索引)
        • 仅排序键(主键或索引)
        • 常规字段(不是键、索引或排序)
        • 混合索引和排序(index1 与 index2 的排序)\
        • ...

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

        【讨论】:

          猜你喜欢
          • 2010-09-29
          • 1970-01-01
          • 1970-01-01
          • 2011-08-22
          • 2011-09-19
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 2019-11-24
          相关资源
          最近更新 更多