1

次のように、フィルターを 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つが作成される可能性があります。(faculty、つまり 362880) 異なる実行計画を実行しますが、デフォルトではオプティマイザはその組み合わせの爆発を避けるために 192 の計画で停止します。そして、計画の数がその数に達すると、オプティマイザは全体的な最適化ランタイムに上限を設けるために、それ以上の最適化の適用を停止します。

これが、2 番目のクエリでEnumerateCollectionNodeがIndexNodeに変換されない理由です。すでに非常に多くの実行計画があるため、オプティマイザーはこのステップの前に停止しました。

最初のクエリでは、オプティマイザは FOR ループ内を自由に移動できません。これは、FILTER ステートメントが一部の移動を制限しているためです。そのため、それほど多くの実行計画が生成されず、時期尚早に最適化を停止することもありません。

リリース 3.0.2 には、これに対する修正が含まれています。その前の一時的な回避策は、2 番目のクエリの 1 つの FILTER ステートメントを複数の小さな FILTER ステートメントに分割し、それらをそれぞれの FOR ループの近くに移動することです。

于 2016-07-04T15:37:09.293 に答える