1

当我尝试仅使用一个过滤器在 ArangoDB 中执行内部联接时,如下所示:

FOR doc1 in catalogue
FOR doc2 in RepoNodes
 FOR doc3 in RepoEdges
 FOR doc4 in RepoNodes
   FOR doc5 in RepoEdges
          FOR doc6 in RepoNodes
            FOR doc10 in catalogue
             FOR doc11 in similarities
              FOR doc12 in clearance

 FILTER doc1.trackid== "TRAAAAK128F9318786" AND doc1.trackid==doc2.mongodbsongs
AND doc3._from==doc2._id AND doc3._to ==doc4._id AND doc5._from==doc4._id and    doc6._id ==doc5._to
AND   doc10.trackid== doc6.mongodbsongs
AND doc11._from==CONCAT("Tracks/",doc6.neo4jSong)
AND doc6.redisclearance== doc12._key
         return {doc10,doc11,doc12}

我注意到索引被忽略了..我的意思是..它执行完整的集合扫描。如果我序列化相同的查询,它会完美运行。我不明白为什么..如果我在最后 4 个 FOR 之前停下来没关系.. 问题出在哪里?为什么需要完整的收藏扫描?

4

1 回答 1

2

在后一个查询(不使用索引的查询)中,查询优化器执行一个函数,该函数将在查询中移动 FOR 循环。它将尝试创建不改变查询含义的所有可能的 FOR 循环排列。

在后一个查询中,优化器可以自由移动 9 个 FOR 循环中的任何一个,因为它们之间没有可能有问题的 FILTER 语句。在这里,优化器将开始创建新的执行计划,并移动 FOR 循环。这可以创造 9! (教师,即 362880)不同的执行计划,但默认情况下优化器停止在 192 个计划,以避免组合爆炸。当达到该计划数量时,优化器将停止应用一些进一步的优化,以限制整体优化运行时间。

这就是为什么在第二个查询中EnumerateCollectionNode没有转换为IndexNode的原因。优化器在这一步之前就停止了,因为已经有太多的执行计划了。

在第一个查询中,优化器不能自由地在 FOR 循环中移动,因为 FILTER 语句限制了一些移动。正因为如此,它不会生成尽可能多的执行计划,也不会过早停止优化。

3.0.2 版包含对此的修复。在此之前的临时解决方法是将第二个查询中的一个 FILTER 语句拆分为多个较小的 FILTER 语句,并将它们移动到各自的 FOR 循环附近。

于 2016-07-04T15:37:09.293 回答