est un diagramme pour vous donner ci-dessous une idée générale de la façon dont mon graphique est structuré:Neo4j: Les mauvaises performances lorsque vous faites une « jointure » sur une chaîne de nœuds
http://i.stack.imgur.com/hbn0J.png
Il contient simplement: nœuds de personne qui sont attachés à un: PersonType. Chacun: Une personne peut exprimer zéro ou plusieurs opinions. Ces opinions sont soit des opinions authentiques (: Opinion) soit des opinions empruntées à quelqu'un d'autre (: OpinionProxy). An: OpinionProxy ou un: Opinion a toujours un et un seul: relation EXPRESSÉ.
j'ai écrit une requête Cypher pour répondre à la question suivante: Donne-moi toutes les opinions exprimées par tous les « Cool Guys », et pour chaque avis, la chaîne de personnes que cette opinion est passé par.
Exemple avec les données de l'échantillon:
+--------------------+---------------------+---------------------+
| person | opinion | influence |
+--------------------+---------------------+---------------------+
| "Dan" | o4 | "Dan" |
+--------------------+---------------------+---------------------+
| "Dan" | o3 | "Dan", "Jim", "Jay" |
+--------------------+---------------------+---------------------+
| "Bob" | ... | ... |
+--------------------+---------------------+---------------------+
Voici une requête qui recherche toutes les opinions de tous les "Cool Guys":
MATCH
(:PersonType {name: "Cool Guys"})<-[:OF_TYPE]-(p:Person)-[:EXPRESSES]->(o),
opath=(o)-[:REFERENCES*0..]->(op:Opinion)
RETURN p.name AS person, op AS opinion, opath
Jusqu'à présent, si bon. Maintenant, la partie complexe vient d'essayer de retourner la chaîne de: Personne plutôt qu'une chaîne de: OpinionProxy - [* 0 ..] ->: Opinion. Voici ma tentative:
MATCH
(:PersonType {name: "Cool Guys"})<-[:OF_TYPE]-(p:Person)-[:EXPRESSES]->(o),
opath=(o)-[:REFERENCES*0..]->(op:Opinion)
MATCH (x)<-[:EXPRESSES]-(opAuthor:Person)
WHERE x IN nodes(opath)
RETURN p.name AS person, op AS opinion, collect(opAuthor) AS influence
Cette requête renvoie exactement ce que je veux, sauf qu'il fonctionne de manière extrêmement lente .
Pour vous donner une idée, dans mon environnement de test, j'ai environ 3000: Personne (y compris 70 "Cool Guys"), 3000: Opinion et 3000: OpinionProxy. Temps de réponse:
- Requête 1: complète dans environ 200ms
- Requête 2: la complète dans A propos 3200ms
C'est un ordre d'augmentation de magnitude juste "rejoindre" la: personne associée à un: Opinion ou: OpinionProxy. Pour Neo4j c'est juste un pointeur à suivre et je ne m'attendais pas à voir un tel écart de performance entre ces deux requêtes.
Y at-il un problème avec ma deuxième requête? Comment puis-je l'optimiser?
Nous vous remercions de votre réponse. Bien que votre requête renvoie toujours l'ensemble de données correct, elle s'exécute également lentement. – Zelbus
Pouvez-vous générer un plan d'exécution pour votre requête? Exécutez votre requête dans le neo4-shell précédé de "profile" comme ceci: profile MATCH (: PersonType ... –
Voici le profil de la requête d'origine et de votre version: http://pastebin.com/x6T2A7MQ. beaucoup pour regarder dans cela! – Zelbus