我有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
1条答案
按热度按时间jogvjijk1#
如果您需要交集,则可以简单地将子查询组合成一个具有四个
FILTER
子句的,其作用类似于自然的AND
。您可能必须使用所有这些数据行建立索引,但应该可以运作。否则,您可以根据先前的数据集进行限制,以减少后续的数据集。如果搜寻跨越集合,或无法建立索引时,这会特别有用: