[英]ArangoDB - Optimize Intersection of Multiple Queries
I have 4 queries to get the INTERSECTED result from them and do a nested FOR on the next line.我有 4 个查询来从中获取 INTERSECTED 结果并在下一行执行嵌套 FOR。 Is there a way to optimize this query?
有没有办法优化这个查询?
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
If you need an intersection, then you could simply combine the subqueries into a single with four FILTER
clauses, which act like a natural AND
.如果您需要一个交集,那么您可以简单地将子查询组合成一个带有四个
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
)
You might have to create an index with all of those columns, but it should work.您可能必须为所有这些列创建一个索引,但它应该可以工作。 Otherwise, you could reduce subsequent datasets by limiting based on the previous.
否则,您可以通过基于先前的限制来减少后续数据集。 This is especially useful if the search crosses collections or indexing is not possible/rational:
如果搜索跨越 collections 或索引不可能/合理,这将特别有用:
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
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.