2017-04-12 2 views
0

Hier ist eine Abfrage, die ich laufen:Neo4j: Optimierung `WHERE` auf Beziehung Eigenschaft

match (n:User), 
(n) -[r]-> (p:Platform {id:"apple"}), 
(n) -[l]-> (lang:Language {id: "en"}), 
(n) -[photos:REL]-> (:Event {type: "photo_upload"}) 
return * LIMIT 30 

Das läuft ziemlich schnell (30-40ms) mit Schema-Indizes. Aber die folgenden verlangsamt ziemlich viel (> 1000 ms):

match (n:User), 
(n) -[r]-> (p:Platform {id:"apple"}), 
(n) -[l]-> (lang:Language {id: "en"}), 
(n) -[photos:REL]-> (:Event {type: "photo_upload"}) 
WHERE photos.count > 10 
return * LIMIT 30 

Es gibt nur 3000 Knoten die erste Abfrage passende aber das Hinzufügen WHERE es verlangsamt wurde auf 1 Sekunde nach unten. Ich weiß, dass wir keine Beziehungseigenschaftsindizes haben, aber selbst dann würde naives Durchlaufen von 3000 Knoten keine 1 Sekunde dauern, also denke ich, dass ich etwas falsch mache, da es anscheinend nicht die WHERE auf den übereinstimmenden Knoten ausführt aber läuft vor dem Abgleich. Wie kann ich das optimieren?

PROFILE Plan für die erste Abfrage: http://imgur.com/a/skACV

PROFILE Plan für die zweite: http://imgur.com/a/b6vx9

EDIT: Weitere Untersuchungen:

Als ich setzen SKIP, verlangsamt es viel nach unten. Es scheint also nicht die Übereinstimmungen auf jedem Pfad zu filtern, sondern alle einzeln und dann zusammenzuführen, was es verlangsamt. Gibt es eine Möglichkeit, es auf den Ergebnissen

+0

Haben Sie versucht, Ihre Abfrage mit PROFILE auszuführen? Können Sie den von der profilierten Abfrage zurückgegebenen Abfrageplan zu Ihrer Beschreibung hinzufügen (indem Sie zunächst alle Elemente des Plans erweitern)? – InverseFalcon

+0

@InverseFalcon Aktualisiert – khajvah

+0

Um klar zu sein, ist die DB genau das, wenn die 2 Abfragen ausgeführt werden? – cybersam

Antwort

0

In Ihre Kommentare nur zu machen, entsprechen, beobachtet man, dass auf die spezifischen Platform, Language und Event Knoten beschleunigt die Dinge zuerst übereinstimmen. Dies hat dazu beigetragen, dass die Suche nur auf die Pfade fokussiert wurde, die für diese spezifischen Knoten relevant sind. Der Cypher-Planer ist nicht immer ausgeklügelt genug, um den effizientesten Plan zu finden. Manchmal muss man ihm also helfen.

Die folgende Abfrage sollte effizient sein, wenn Sie einen Index (oder Eindeutigkeitsbeschränkung) unter :Platform(id), :Language(id) und :Event(type) erstellt haben.

MATCH (p:Platform {id:"apple"}), (lang:Language {id: "en"}), (e:Event {type: "photo_upload"}) 
USING INDEX p:Platform(id) 
USING INDEX lang:Language(id) 
USING INDEX e:Event(type) 
MATCH (n:User)-[r]->(p), (n)-[l]->(lang), (n)-[photos:REL]->(e) 
WHERE photos.count > 10 
RETURN * 
LIMIT 30 

Beachten Sie, dass ich 3 separate Hinweise auf die Cypher Planer zu geben hatten die drei Indizes zu verwenden (oder Einzigartigkeit Einschränkungen), wie der Planer höchstens einen Index auf seinem eigenen verwenden zu bevorzugen scheint. Sie sollten die schnellsten Ergebnisse erzielen, wenn Sie alle 3 Indizes verwenden, um schnell die 3 Knoten zu erhalten, mit denen die Suche beginnt.

Verwandte Themen