【问题标题】:Arango DB performace: edge vs. DOCUMENT()Arangodb 性能:edge 与 DOCUMENT()
【发布时间】:2017-09-06 07:15:48
【问题描述】:

我是使用图表的 arangoDB 新手。我只是想知道在不需要查询图形的非常简单的 1:1 连接中构建边或使用“DOCUMENT()”是否更快?

LET a = DOCUMENT(@from)
FOR v IN OUTBOUND a
CollectionAHasCollectionB
RETURN MERGE(a,{b:v})

LET a = DOCUMENT(@from)
RETURN MERGE(a,{b:DOCUMENT(a.bId)}

【问题讨论】:

  • 我发现在生成的文档非常大的深层嵌套循环中使用 DOCUMENT() 会显着降低性能并可能导致数据库崩溃。

标签: graph arangodb query-performance aql


【解决方案1】:

您可以尝试一个简单的基准测试:

创建集合productscategories 和边缘集合has_category。然后生成一些样本数据:

FOR i IN 1..10000
    INSERT {_key: TO_STRING(i), name: CONCAT("Product ", i)} INTO products
FOR i IN 1..10000
    INSERT {_key: TO_STRING(i), name: CONCAT("Category ", i)} INTO categories
FOR p IN products
    LET random_categories = (
    FOR c IN categories
        SORT RAND()
        LIMIT 5
        RETURN c._id
    )
    LET category_subset = SLICE(random_categories, 0, RAND()*5+1)

    UPDATE p WITH {
        categories: category_subset,
        categoriesEmbedded: DOCUMENT(category_subset)[*].name
    } INTO products

    FOR cat IN category_subset
        INSERT {_from: p._id, _to: cat} INTO has_category

然后比较不同方法的查询时间。

图遍历(深度 1..1):

FOR p IN products
    RETURN {
        product: p.name,
        categories: (FOR v IN OUTBOUND p has_category RETURN v.name)
    }

使用 DOCUMENT() 在类别集合中查找:

FOR p IN products
    RETURN {
        product: p.name,
        categories: DOCUMENT(p.categories)[*].name
    }

使用直接嵌入的类别名称:

FOR p IN products
    RETURN {
        product: p.name,
        categories: p.categoriesEmbedded
    }

图遍历是所有 3 个中最慢的,在另一个集合中的查找比遍历更快,但迄今为止最快的查询是嵌入类别名称的查询。

但是,如果您只查询一种或几种产品的类别,则无论数据模型和查询方法如何,响应时间都应该在亚毫秒范围内,因此不会造成性能问题。

如果您需要查询具有可变深度、长路径、最短路径等的路径,则应选择图形方法。对于您的用例,这不是必需的。嵌入式方法是否合适是您需要决定的:

  • 重复信息是否可以接受,并且可能存在数据不一致? (如果要更改类别名称,则需要在所有产品记录中更改它,而不是只更改一个类别文档,产品可以通过不可变ID引用)

  • 每个类别是否有很多附加信息?如果是这样,所有这些数据都需要嵌入到具有该类别的每个产品文档中——基本上是用内存/存储空间来换取性能

  • 您是否需要经常检索所有(不同)类别的列表?您可以使用单独的类别集合非常便宜地执行此类查询。使用嵌入式方法,效率会低得多,因为您需要检查所有产品并收集类别信息。

底线:您应该选择最适合您的用例的数据模型和方法。由于 ArangoDB 的多模型特性,如果您的用例发生变化或遇到性能问题,您可以轻松尝试另一种方法。

【讨论】:

    【解决方案2】:

    一般来说,后一种变体

    LET a = DOCUMENT(@from)
    RETURN MERGE(a,{b:DOCUMENT(a.bId)}
    

    应该比全功能遍历变体具有更低的开销。这是因为 DOCUMENT 变体将对文档进行点查找,而遍历变体是非常通用的:它可以从可变数量的集合返回零到多个结果,需要跟踪看到的路径等。

    当我在本地测试用例中尝试这两种变体时,非遍历变体也快了很多,支持了这一说法。

    但是,基于遍历的变体更加灵活:它也可以用于多条边(非 1:1 映射)和更长的路径。

    【讨论】:

      猜你喜欢
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多