私は のコア開発者の 1 人であり、ArangoDB
クエリの最適化を試みました。私はあなたを持っていないので、dataset
私は自分のテストについてしか話すことができずdataset
、私の結果を検証していただければ幸いです.
まず、ArangoDB
2.7 で実行している場合ですが、この特定のケースでは、2.6 との大きなパフォーマンスの違いは期待できません。
私のdataset
場合、クエリをそのまま 7 秒以内に実行できました。最初の修正: あなたの友人のステートメントではincludeData: true
、_id
. をincludeData: false
GRAPH_NEIGHBORS
直接返す_id
と、ここでサブクエリを取り除くこともできます
LET friends = GRAPH_NEIGHBORS('graph',
@user,
{"direction": "any",
"edgeExamples": {
name: "FRIENDS_WITH"
}})
これにより、私のマシンでは〜1.1秒になりました。なのでNeo4Jに近い性能になると思います。
なぜこれが大きな影響を与えるのですか?
内部的には_id
、ドキュメント JSON を実際にロードせずに、最初に値を見つけます。クエリでは、このデータは必要ないため、開かずに安全に続行できます。
しかし、今は本当の改善のために
あなたのクエリは「論理的な」方法で進み、最初にユーザーの隣人を取得し、隣人を見つけて、 afoaf
が見つかった頻度を数えて並べ替えます。これは、完全な foaf ネットワークをメモリ内に構築し、全体としてソートする必要があります。
別の方法でそれを行うこともできます: 1. ユーザーのすべてfriends
を検索 ( のみ_ids
) 2. すべてを検索foaf
(完全なドキュメント) 3. それぞれについてfoaf
すべてを検索foaf_friends
( のみ) 4.と_ids
の交点を検索し、それらをカウントしますfriends
foaf_friends
このクエリは次のようになります。
LET fids = GRAPH_NEIGHBORS("graph",
@user,
{
"direction":"any",
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
FOR foaf IN GRAPH_NEIGHBORS("graph",
@user,
{
"minDepth": 2,
"maxDepth": 2,
"direction": "any",
"includeData": true,
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
LET commonIds = GRAPH_NEIGHBORS("graph",
foaf._id, {
"direction": "any",
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
LET common_friend_count = LENGTH(INTERSECTION(fids, commonIds))
SORT common_friend_count DESC
RETURN {user: foaf, common_friend_count: common_friend_count}
私のテストグラフでは、〜0.024秒で実行されました
したがって、これにより実行時間が250倍速くなり、Neo4jでの現在のクエリよりも高速になると予想されますが、持っていないdataset
ので確認できません。実行して教えていただければ幸いです.
最後に一つだけ
の場合edgeExamples: {name : "FRIENDS_WITH" }
は の場合と同じですがincludeData
、この場合、実際のエッジを見つけて調べる必要があります。名前に基づいてエッジを別のコレクションに保存すると、これを回避できます。そして、edgeExamples も削除します。これにより、パフォーマンスがさらに向上します (特にエッジが多い場合)。
未来
次のリリースにご期待ください。現在、AQL にいくつかの機能を追加しています。これにより、ケースのクエリがはるかに簡単になり、パフォーマンスがさらに向上するはずです。