Ich bin einer der Kernentwickler von ArangoDB
und versuchte, Ihre Abfrage zu optimieren. Da ich Ihre dataset
nicht habe, kann ich nur über meinen Test sprechen dataset
und wäre glücklich zu hören, wenn Sie meine Ergebnisse validieren können.
Zuerst, wenn alle ich auf ArangoDB
2.7 laufen, aber in diesem speziellen Fall erwarte ich keinen großen Leistungsunterschied zu 2.6.
In meinem dataset
konnte ich Ihre Abfrage ausführen, wie es in ~ 7sec ist. Erste Lösung: In Ihrer Freunde-Anweisung verwenden Sie includeData: true
und geben nur die _id
zurück. Mit includeData: false
GRAPH_NEIGHBORS
liefert direkt die _id
und wir können auch hier der Subquery
LET friends = GRAPH_NEIGHBORS('graph',
@user,
{"direction": "any",
"edgeExamples": {
name: "FRIENDS_WITH"
}})
Das hat es loszuwerden bis ~ 1,1 sec auf meinem Rechner. Also erwarte ich, dass dies der Leistung von Neo4J nahe kommt.
Warum hat dies eine hohe Auswirkung? Intern finden wir zuerst den _id
Wert, ohne die Dokumente JSON tatsächlich zu laden. In Ihrer Anfrage benötigen Sie keine dieser Daten, so dass wir sicher fortfahren können, sie nicht zu öffnen.
Aber jetzt für die wirkliche Verbesserung
Ihre Abfrage des „logischen“ Weg geht und bekommt erste Nutzer Nachbarn, als ihre Nachbarn findet, zählt, wie oft ein foaf
und es sortiert gefunden wird. Dies muss das komplette Foaf-Netzwerk im Speicher aufbauen und es als Ganzes sortieren.
Sie können es auch tun, in einer anderen Art und Weise: 1. Alle Benutzer suchen friends
(nur _ids
) 2. Hier finden Sie alle foaf
(vollständige Dokument) 3. Für jeden foaf
alle foaf_friends
finden (nur _ids
) 4. Suchen sie die Kreuzung von friends
und foaf_friends
und COUNT sie
diese Abfrage dies möchte:
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}
Was in meinem Testgraph wurde in ~ 0 ausgeführt.024 sec
So gab diesen mir einen Faktor 250 schnelle Ausführungszeit, und ich würde erwarten, dass dies schneller sein als die aktuelle Abfrage in Neo4j, aber da ich nicht habe Ihre dataset
ich es nicht überprüfen kann, es wäre gut, wenn du es tun könntest und es mir erzählst.
Eine letzte Sache
Mit dem edgeExamples: {name : "FRIENDS_WITH" } it is the same as with
includeData`, in diesem Fall wir die wirkliche Kante zu finden, und schauen hinein. Dies könnte vermieden werden, wenn Sie Ihre Kanten in separaten Sammlungen basierend auf ihrem Namen speichern. Und entfernen Sie dann auch die edgeExamples. Dies wird die Leistung weiter erhöhen (besonders wenn es viele Kanten gibt).
Zukunft
Aufenthalt für unsere nächste Veröffentlichung abgestimmt werden wir jetzt noch mehr Funktionalität zu AQL Zugabe, die Ihren Fall machen wird viel einfacher abfragen und sollte eine weitere Leistungssteigerung geben.
Danke! Ich überprüfe, bestätige und akzeptiere deine Antwort Montag! Wir schätzen es sehr, dass Sie sich die Zeit genommen haben, unsere Frage zu beantworten;) –
In unserem Fall war Ihre erste Verbesserung deutlich schneller als unsere Version. Vor allem unsere langsamsten Abfragen haben von Ihren Verbesserungen profitiert. Es hat tatsächlich das AQL-Ergebnis der Neo4j-Version sehr nahe gebracht. Wie für die zweite Abfrage - es machte unsere Worst-Case Foaf-Abfragen schneller, aber der Best-Case-Abfragen ein bisschen langsamer :(. Wie auch immer, die erste Verbesserung hat uns sehr geholfen;). –