cypher - How can I optimise a Neo4j MERGE query on a node with many relationships? -
i have graph node has many outgoing relationships. time takes add new outgoing relationships degrades add more relationships. degradation appears due time taken check relationship doesn't exist (i'm using merge add relationships).
the destination nodes of relationships have few relationships themselves. there way can force neo4j check existence of relationship destination node instead of source node?
here's test script reproduce problem. creates 1 node id 0 followed 1000 nodes connected node 0 has relationship. nodes added execution time increases linearly.
create constraint on (n:node) assert n.id unique unwind range(1,1000) merge (from:node { id: 0 }) merge (to:node { id: i}) merge (from)-[:has]->to added 1001 labels, created 1001 nodes, set 1001 properties, created 1000 relationships, statement executed in 3496 ms.
unwind range(1001,2000) merge (from:node { id: 0 }) merge (to:node { id: i}) merge (from)-[:has]->to added 1000 labels, created 1000 nodes, set 1000 properties, created 1000 relationships, statement executed in 7030 ms.
unwind range(2001,3000) merge (from:node { id: 0 }) merge (to:node { id: i}) merge (from)-[:has]->to added 1000 labels, created 1000 nodes, set 1000 properties, created 1000 relationships, statement executed in 10489 ms.
unwind range(3001,4000) merge (from:node { id: 0 }) merge (to:node { id: i}) merge (from)-[:has]->to added 1000 labels, created 1000 nodes, set 1000 properties, created 1000 relationships, statement executed in 14390 ms.
if create used instead of merge performance better. can't use create though because want ensure relationships unique.
unwind range(4001,5000) merge (from:node { id: 0 }) merge (to:node { id: i}) create (from)-[:has]->to added 1000 labels, created 1000 nodes, set 1000 properties, created 1000 relationships, statement executed in 413 ms.
note: tested neo4j v2.2.2
this because cypher not clever enough yet use degree of nodes when executing merge. in cost optimizer used reads cleverer updates old rule optimizer used.
after playing around bit unsuccessfully * changing order of & * using create unique instead of merge * trying use path-expressions use get-degree in cost
i remembered shortestpath takes degree's account , goes left right
so tried combine create, , worked well, here example 100.000 nodes.
neo4j-sh (?)$ create constraint on (n:node) assert n.id unique; +-------------------+ | no data returned. | +-------------------+ constraints added: 1 1054 ms neo4j-sh (?)$ neo4j-sh (?)$ unwind range(0,100000) create (to:node { id: i}); +-------------------+ | no data returned. | +-------------------+ nodes created: 100001 properties set: 100001 labels added: 100001 2375 ms neo4j-sh (?)$ neo4j-sh (?)$ neo4j-sh (?)$ match (from:node { id: 0 }) > unwind range(1,100000) > match (to:node { id: i}) > shortestpath((to)<-[:has]-(from)) null > create (from)-[:has]->(to); +-------------------+ | no data returned. | +-------------------+ relationships created: 100000 2897 ms neo4j-sh (?)$ neo4j-sh (?)$ neo4j-sh (?)$ match (from:node { id: 0 }) > unwind range(1,100000) > match (to:node { id: i}) > shortestpath((to)<-[:has]-(from)) null > create (from)-[:has]->(to); +--------------------------------------------+ | no data returned, , nothing changed. | +--------------------------------------------+ 2360 ms
Comments
Post a Comment