简体   繁体   中英

Neo4j Cypher Performance of Optional Match

I'm trying to write a query to count the total number of votes for an election grouped by the state in which they were cast. I'd like all states to be returned even if there are 0 votes. The following query uses optional match to return all states regardless of whether or not any votes have been cast.

MATCH (state:State)
OPTIONAL MATCH (state)<-[:FROM]-(:User)-[:CAST]->(vote:Vote)-[:FOR]->(:Election{id:'ABC123'})
RETURN state, count(vote)

returns 50 rows in in 3064ms .

If I remove the optional match the query performs much better :

MATCH (state:State),(state)<-[:FROM]-(:User)-[:CAST]->(vote:Vote)-[:FOR]->(:Election{id:'ABC123'})
RETURN state, count(*)

returns 49 rows in 406ms .

My questions are

  1. Why is there such a huge discrepancy in performance between the two queries ?

  2. Is there a better way to structure the query to improve performance and still meet the requirement?

What about using a Union statement?:

MATCH (s:State)
RETURN s
UNION MATCH (s:State)<-[:FROM]-(:User)-[:CAST]->(vote:Vote)-[:FOR]->(:Election{id:'ABC123'}) RETURN s, count(vote)

I think your query may be taking so long due to the mechanics of the optional match vis a vis the count(vote) operation. I'm not sure if this will be faster, but it might be worth a try.

Union Docs
Optional Match Docs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM