2016-05-03 4 views
0

ich ein Diagramm haben, wobei jeder Knoten entweder A oder B hat, und ein Index für die ID-Eigenschaft für jedes Etikett beschriften:Neo4j Indizes langsam, wenn über 2 Etiketten Abfrage

CREATE INDEX ON :A(id); 
CREATE INDEX ON :B(id); 

In diesem Diagramm I Ich möchte den/die Knoten mit der ID "42" finden, aber ich kenne das Etikett nicht a priori. Dazu führe ich die folgende Abfrage aus:

MATCH (n {id:"42"}) WHERE (n:A OR n:B) RETURN n; 

Diese Abfrage dauert jedoch 6 Sekunden. Es wird jedoch entweder:

MATCH (n:A {id:"42"}) RETURN n; 
MATCH (n:B {id:"42"}) RETURN n; 

dauert nur ~ 10ms.

Formuliere ich meine Anfrage nicht korrekt? Wie kann man es so formulieren, dass es die installierten Indizes nutzt?

Antwort

2

Hier ist eine Möglichkeit, beide Indizes zu verwenden. result wird eine Sammlung von übereinstimmenden Knoten sein.

OPTIONAL MATCH (a:B {id:"42"}) 
OPTIONAL MATCH (b:A {id:"42"}) 
RETURN 
    (CASE WHEN a IS NULL THEN [] ELSE [a] END) + 
    (CASE WHEN b IS NULL THEN [] ELSE [b] END) 
    AS result; 

sollten Sie PROFILE verwenden, um sicherzustellen, dass der Ausführungsplan für Ihre Neo4j Umgebung verwendet die NodeIndexSeek Betrieb für beide OPTIONAL MATCH Klauseln. Wenn nicht, können Sie die USING INDEX-Klausel verwenden, um Cypher einen Hinweis zu geben.

1

Indizes werden gebildet und über eine Knotenbeschriftung und -eigenschaft verwendet. Um sie zu verwenden, müssen Sie Ihre Abfrage auf die gleiche Weise erstellen. Das bedeutet, dass Abfragen ohne Label alle Knoten mit den Ergebnissen durchsuchen, die Sie erhalten haben.

2

Sie sollten UNION verwenden, um sicherzustellen, dass beide Indizes verwendet werden. In Ihrer Frage hatten Sie fast die Antwort.

MATCH (n:A {id:"42"}) RETURN n 
UNION 
MATCH (n:B {id:"42"}) RETURN n 
; 

Dies wird funktionieren. Überprüfen Sie Ihr Abfrageprofil oder erklären Sie vor Ihrer Abfrageanweisung, ob die Indizes verwendet werden.