ArangoDB-优化多个查询的交集

问题描述 投票:0回答:1

我有4个查询,从中获取相交的结果,并在下一行执行嵌套的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个回答
0
投票

如果需要交集,则可以将子查询简单地合并为带有四个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 c3
        FILTER attr.key == "mlt1" AND attr.value == "mo2"
        RETURN attr.productId
)
© www.soinside.com 2019 - 2024. All rights reserved.