【问题标题】:ArangoDB - Optimize Intersection of Multiple QueriesArangoDB - 优化多个查询的交集
【发布时间】:2020-05-12 08:33:44
【问题描述】:

我有 4 个查询来从中获取 INTERSECTED 结果并在下一行执行嵌套 FOR。 有没有办法优化这个查询?

Query string:
 LET c0 = (FOR attr IN products_attributes
     FILTER attr.key == "nt1" AND attr.value >= 0 AND attr.value <= 5
 RETURN attr.productId)
 LET c1 = (FOR attr IN products_attributes
     FILTER attr.key == "st1" AND attr.value == "test str"
 RETURN attr.productId)
 LET c2 = (FOR attr IN products_attributes
     FILTER attr.key == "mlt1" AND attr.value == "mo1"
 RETURN attr.productId)
 LET c3 = (FOR attr IN products_attributes
     FILTER attr.key == "mlt1" AND attr.value == "mo2"
 RETURN attr.productId)
 LET collections = INTERSECTION(c0, c1, c2, c3)
 FOR pid IN collections
     FOR p IN products
         FILTER p._key == pid AND "test" IN p.st AND "product" IN p.st
         SORT p.date DESC
         LIMIT 0, 10
         RETURN p

Execution plan:
 Id   NodeType            Est.   Comment
  1   SingletonNode          1   * ROOT
  8   SubqueryNode           1     - LET c0 = ...   /* const subquery */
  2   SingletonNode          1       * ROOT
 40   IndexNode              1         - FOR attr IN products_attributes   /* persistent index scan */
  6   CalculationNode        1           - LET #21 = attr.`productId`   /* attribute expression */   /* collections used: attr : products_attributes */
  7   ReturnNode             1           - RETURN #21
 15   SubqueryNode           1     - LET c1 = ...   /* const subquery */
  9   SingletonNode          1       * ROOT
 41   IndexNode              0         - FOR attr IN products_attributes   /* persistent index scan */
 13   CalculationNode        0           - LET #25 = attr.`productId`   /* attribute expression */   /* collections used: attr : products_attributes */
 14   ReturnNode             0           - RETURN #25
 22   SubqueryNode           1     - LET c2 = ...   /* const subquery */
 16   SingletonNode          1       * ROOT
 42   IndexNode              0         - FOR attr IN products_attributes   /* persistent index scan */
 20   CalculationNode        0           - LET #29 = attr.`productId`   /* attribute expression */   /* collections used: attr : products_attributes */
 21   ReturnNode             0           - RETURN #29
 29   SubqueryNode           1     - LET c3 = ...   /* const subquery */
 23   SingletonNode          1       * ROOT
 43   IndexNode              0         - FOR attr IN products_attributes   /* persistent index scan */
 27   CalculationNode        0           - LET #33 = attr.`productId`   /* attribute expression */   /* collections used: attr : products_attributes */
 28   ReturnNode             0           - RETURN #33
 30   CalculationNode        1     - LET collections = INTERSECTION(c0, c1, c2, c3)   /* simple expression */
 39   IndexNode              1     - FOR p IN products   /* persistent index scan */
 35   CalculationNode        1       - LET #37 = p.`date`   /* attribute expression */   /* collections used: p : products */
 31   EnumerateListNode    100       - FOR pid IN collections   /* list iteration */
 44   CalculationNode      100         - LET #35 = (("product" in p.`st`) && (p.`_key` == pid))   /* simple expression */   /* collections used: p : products */
 34   FilterNode           100         - FILTER #35
 36   SortNode             100         - SORT #37 DESC
 37   LimitNode             10         - LIMIT 0, 10
 38   ReturnNode            10         - RETURN p

Indexes used:
 By   Type         Collection            Unique   Sparse   Selectivity   Fields               Ranges
 40   persistent   products_attributes   true     false            n/a   [ `key`, `value` ]   ((attr.`key` == "nt1") && (attr.`value` >= 0) && (attr.`value` <= 5))
 41   persistent   products_attributes   true     false            n/a   [ `key`, `value` ]   ((attr.`key` == "st1") && (attr.`value` == "test str"))
 42   persistent   products_attributes   true     false            n/a   [ `key`, `value` ]   ((attr.`key` == "mlt1") && (attr.`value` == "mo1"))
 43   persistent   products_attributes   true     false            n/a   [ `key`, `value` ]   ((attr.`key` == "mlt1") && (attr.`value` == "mo2"))
 39   persistent   products              false    false            n/a   [ `st[*]` ]          ("test" in p.`st`)

Optimization rules applied:
 Id   RuleName
  1   move-calculations-up
  2   move-filters-up
  3   interchange-adjacent-enumerations
  4   move-calculations-up-2
  5   move-filters-up-2
  6   use-indexes
  7   remove-filter-covered-by-index
  8   remove-unnecessary-calculations-2


【问题讨论】:

    标签: optimization query-optimization intersection arangodb aql


    【解决方案1】:

    如果您需要一个交集,那么您可以简单地将子查询组合成一个带有四个FILTER 子句的单个子查询,它们的作用类似于自然的AND

    LET collections = (
        FOR attr IN products_attributes
            FILTER attr.key == "nt1" AND attr.value >= 0 AND attr.value <= 5
            FILTER attr.key == "st1" AND attr.value == "test str"
            FILTER attr.key == "mlt1" AND attr.value == "mo1"
            FILTER attr.key == "mlt1" AND attr.value == "mo2"
            RETURN attr.productId
    )
    

    您可能必须为所有这些列创建一个索引,但它应该可以工作。否则,您可以通过基于先前的限制来减少后续数据集。如果搜索跨集合或索引不可能/合理,这将特别有用:

    LET c0 = (
        FOR attr IN products_attributes
            FILTER attr.key == "nt1" AND attr.value >= 0 AND attr.value <= 5
            RETURN attr.productId
    )
    LET c1 = (
        FOR attr IN products_attributes
            FILTER attr.productId in c0
            FILTER attr.key == "st1" AND attr.value == "test str"
            RETURN attr.productId
    )
    LET c2 = (
        FOR attr IN products_attributes
            FILTER attr.productId in c1
            FILTER attr.key == "mlt1" AND attr.value == "mo1"
            RETURN attr.productId
    )
    LET c3 = (
        FOR attr IN products_attributes
            FILTER attr.productId in c2
            FILTER attr.key == "mlt1" AND attr.value == "mo2"
            RETURN attr.productId
    )
    

    【讨论】:

    • 这给了我一个空的结果
    • @zero.zero.seven,也许您可​​以提供更多信息,尤其是在否决回复之前。有点让人不想帮你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多