The USING
clause is used to influence the decisions of the planner when building an execution plan for a query.
Caution
Forcing planner behavior is an advanced feature, and should be used with caution by experienced developers and/or database administrators only, as it may cause queries to perform poorly. |
Introduction
When executing a query, Neo4j needs to decide where in the query graph to start matching.
This is done by looking at the MATCH
clause and the WHERE
conditions and using that information to find useful indexes, or other starting points.
However, the selected index might not always be the best choice. Sometimes multiple indexes are possible candidates, and the query planner picks the wrong one from a performance point of view. And in some circumstances (albeit rarely) it is better not to use an index at all.
You can force Neo4j to use a specific starting point through the USING
clause. This is called giving a planner hint.
There are three types of planner hints: index hints, scan hints, and join hints.
Note
You cannot use planner hints if your query has a |
The following graph is used for the examples below:
Query
MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' }) RETURN 1 AS column
The following query will be used in some of the examples on this page. It has intentionally been constructed in such a way that the statistical information will be inaccurate for the particular subgraph that this query matches. For this reason, it can be improved by supplying planner hints.
Query plan
+------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +ProduceResults | 0 | 1 | 0 | column | column | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Projection | 0 | 1 | 0 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | { AUTOINT3} | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Filter | 0 | 1 | 2 | anon[122], anon[41], anon[68], conway, cs, liskov, wing | liskov:Scientist AND liskov.name == { AUTOSTRING0} | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Expand(All) | 0 | 1 | 3 | anon[41], liskov -- anon[122], anon[68], conway, cs, wing | (wing)<-[:KNOWS]-(liskov) | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Filter | 1 | 2 | 2 | anon[122], anon[68], conway, cs, wing | NOT(anon[122] == anon[68]) AND wing:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Expand(All) | 1 | 3 | 4 | anon[68], wing -- anon[122], conway, cs | (cs)<-[:RESEARCHED]-(wing) | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Filter | 0 | 1 | 4 | anon[122], conway, cs | conway.name == { AUTOSTRING2} AND conway:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Expand(All) | 3 | 3 | 4 | anon[122], conway -- cs | (cs)<-[:RESEARCHED]-(conway) | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +Filter | 1 | 1 | 3 | cs | cs.name == { AUTOSTRING1} | | | +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ | +NodeByLabelScan | 3 | 3 | 4 | cs | :Science | +------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+ Total database accesses: 26
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) RETURN 1 AS column
Index hints
Index hints are used to specify which index, if any, the planner should use as a starting point.
This can be beneficial in cases where the index statistics are not accurate for the specific values that
the query at hand is known to use, which would result in the planner picking a non-optimal index.
To supply an index hint, use USING INDEX variable:Label(property)
after the applicable MATCH
clause.
It is possible to supply several index hints, but keep in mind that several starting points will require the use of a potentially expensive join later in the query plan.
Query using an index hint
The query above will not naturally pick an index to solve the plan. This is because the graph is very small, and label scans are faster for small databases. In general, however, query performance is ranked by the dbhit metric, and we see that using an index is slightly better for this query.
Query
MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' }) USING INDEX liskov:Scientist(name) RETURN liskov.born AS column
Returns the year Barbara Liskov was born.
Query plan
+-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +ProduceResults | 0 | 1 | 0 | column | column | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Projection | 0 | 1 | 1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | liskov.born | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Filter | 0 | 1 | 4 | anon[122], anon[41], anon[68], conway, cs, liskov, wing | conway.name == { AUTOSTRING2} AND NOT(anon[122] == anon[68]) AND conway:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Expand(All) | 0 | 3 | 4 | anon[122], conway -- anon[41], anon[68], cs, liskov, wing | (cs)<-[:RESEARCHED]-(conway) | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Filter | 0 | 1 | 4 | anon[41], anon[68], cs, liskov, wing | cs:Science AND cs.name == { AUTOSTRING1} | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Expand(All) | 0 | 2 | 3 | anon[68], cs -- anon[41], liskov, wing | (wing)-[:RESEARCHED]->(cs) | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Filter | 0 | 1 | 1 | anon[41], liskov, wing | wing:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +Expand(All) | 0 | 1 | 2 | anon[41], wing -- liskov | (liskov)-[:KNOWS]->(wing) | | | +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ | +NodeIndexSeek | 1 | 1 | 2 | liskov | :Scientist(name) | +-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+ Total database accesses: 21
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) RETURN liskov.born AS column
Query using multiple index hints
Supplying one index hint changed the starting point of the query, but the plan is still linear, meaning it only has one starting point. If we give the planner yet another index hint, we force it to use two starting points, one at each end of the match. It will then join these two branches using a join operator.
Query
MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' }) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) RETURN liskov.born AS column
Returns the year Barbara Liskov was born, using a slightly better plan.
Query plan
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +ProduceResults | 0 | 1 | 0 | column | column | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Projection | 0 | 1 | 1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | liskov.born | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Filter | 0 | 1 | 0 | anon[122], anon[41], anon[68], conway, cs, liskov, wing | NOT(anon[122] == anon[68]) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +NodeHashJoin | 0 | 1 | 0 | anon[41], anon[68], liskov, wing -- anon[122], conway, cs | cs | | |\ +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Filter | 1 | 1 | 1 | anon[122], conway, cs | cs.name == { AUTOSTRING1} | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Expand(All) | 1 | 1 | 2 | anon[122], cs -- conway | (conway)-[:RESEARCHED]->(cs) | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +NodeIndexSeek | 1 | 1 | 2 | conway | :Scientist(name) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Filter | 0 | 1 | 4 | anon[41], anon[68], cs, liskov, wing | cs:Science AND cs.name == { AUTOSTRING1} | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Expand(All) | 0 | 2 | 3 | anon[68], cs -- anon[41], liskov, wing | (wing)-[:RESEARCHED]->(cs) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Filter | 0 | 1 | 1 | anon[41], liskov, wing | wing:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Expand(All) | 0 | 1 | 2 | anon[41], wing -- liskov | (liskov)-[:KNOWS]->(wing) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +NodeIndexSeek | 1 | 1 | 2 | liskov | :Scientist(name) | +------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ Total database accesses: 18
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) RETURN liskov.born AS column
Scan hints
If your query matches large parts of an index, it might be faster to scan the label and filter out nodes that do not match.
To do this, you can use USING SCAN variable:Label
after the applicable MATCH
clause.
This will force Cypher to not use an index that could have been used, and instead do a label scan.
Hinting a label scan
If the best performance is to be had by scanning all nodes in a label and then filtering on that set, use USING SCAN
.
Query
MATCH (s:Scientist) USING SCAN s:Scientist WHERE s.born < 1939 RETURN s.born AS column
Returns all scientists born before 1939.
Query plan
+------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+ | +ProduceResults | 0 | 2 | 0 | column | column | | | +----------------+------+---------+-------------+-------------------------------------------------------------------+ | +Projection | 0 | 2 | 2 | column -- s | s.born | | | +----------------+------+---------+-------------+-------------------------------------------------------------------+ | +Filter | 0 | 2 | 7 | s | AndedPropertyComparablePredicates(s,s.born,s.born < { AUTOINT0}) | | | +----------------+------+---------+-------------+-------------------------------------------------------------------+ | +NodeByLabelScan | 7 | 7 | 8 | s | :Scientist | +------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+ Total database accesses: 17
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (s:Scientist) USING SCAN s:Scientist WHERE s.born < 1939 RETURN s.born AS column
Join hints
Join hints are the most advanced type of hints, and are not used to find starting points for the query execution plan, but to enforce that joins are made at specified points. This implies that there has to be more than one starting point (leaf) in the plan, in order for the query to be able to join the two branches ascending from these leaves. Due to this nature, joins, and subsequently join hints, will force the planner to look for additional starting points, and in the case where there are no more good ones, potentially pick a very bad starting point. This will negatively affect query performance. In other cases, the hint might force the planner to pick a seemingly bad starting point, which in reality proves to be a very good one.
Hinting a join on a single node
In the example above using multiple index hints, we saw that the planner chose to do a join on the cs
node.
This means that the relationship between wing
and cs
was traversed in the outgoing direction, which is better
statistically because the pattern ()-[:RESEARCHED]->(:Science)
is more common than the pattern (:Scientist)-[:RESEARCHED]->()
.
However, in the actual graph, the cs
node only has two such relationships, so expanding from it will be beneficial
to expanding from the wing
node. We can force the join to happen on wing
instead with a join hint.
Query
MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' }) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) USING JOIN ON wing RETURN wing.born AS column
Returns the birth date of Jeanette Wing, using a slightly better plan.
Query plan
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +ProduceResults | 0 | 1 | 0 | column | column | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Projection | 0 | 1 | 1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | wing.born | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +NodeHashJoin | 0 | 1 | 0 | anon[41], liskov -- anon[122], anon[68], conway, cs, wing | wing | | |\ +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Filter | 1 | 2 | 0 | anon[122], anon[68], conway, cs, wing | NOT(anon[122] == anon[68]) | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Expand(All) | 1 | 3 | 4 | anon[68], wing -- anon[122], conway, cs | (cs)<-[:RESEARCHED]-(wing) | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Filter | 0 | 1 | 2 | anon[122], conway, cs | cs:Science AND cs.name == { AUTOSTRING1} | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +Expand(All) | 1 | 1 | 2 | anon[122], cs -- conway | (conway)-[:RESEARCHED]->(cs) | | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | | +NodeIndexSeek | 1 | 1 | 2 | conway | :Scientist(name) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Filter | 0 | 1 | 1 | anon[41], liskov, wing | wing:Scientist | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +Expand(All) | 0 | 1 | 2 | anon[41], wing -- liskov | (liskov)-[:KNOWS]->(wing) | | | +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ | +NodeIndexSeek | 1 | 1 | 2 | liskov | :Scientist(name) | +------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+ Total database accesses: 16
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) USING JOIN ON wing RETURN wing.born AS column
Hinting a join on multiple nodes
The query planner can be made to produce a join between several specific points. This requires the query to expand from the same node from several directions.
Query
MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist { name:'Wing' })-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(liskov) USING INDEX liskov:Scientist(name) USING JOIN ON liskov, cs RETURN wing.born AS column
Returns the birth date of Jeanette Wing.
Query plan
+------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +ProduceResults | 0 | 1 | 0 | column | column | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Projection | 0 | 1 | 1 | column -- anon[136], anon[41], anon[82], cs, liskov, wing | wing.born | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Filter | 0 | 1 | 0 | anon[136], anon[41], anon[82], cs, liskov, wing | NOT(anon[136] == anon[82]) | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +NodeHashJoin | 0 | 1 | 0 | anon[41], anon[82], wing -- anon[136], cs, liskov | liskov, cs | | |\ +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | | +Filter | 1 | 1 | 2 | anon[136], cs, liskov | cs.name == { AUTOSTRING2} AND cs:Science | | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | | +Expand(All) | 1 | 1 | 2 | anon[136], cs -- liskov | (liskov)-[:RESEARCHED]->(cs) | | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | | +NodeIndexSeek | 1 | 1 | 2 | liskov | :Scientist(name) | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Filter | 0 | 1 | 4 | anon[41], anon[82], cs, liskov, wing | cs:Science AND cs.name == { AUTOSTRING2} | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Expand(All) | 0 | 2 | 3 | anon[82], cs -- anon[41], liskov, wing | (wing)-[:RESEARCHED]->(cs) | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Filter | 0 | 1 | 2 | anon[41], liskov, wing | wing:Scientist AND wing.name == { AUTOSTRING1} | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +Expand(All) | 0 | 1 | 2 | anon[41], wing -- liskov | (liskov)-[:KNOWS]->(wing) | | | +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ | +NodeIndexSeek | 1 | 1 | 2 | liskov | :Scientist(name) | +------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+ Total database accesses: 20
Try this query live CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist {name:'Wing'})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(liskov) USING INDEX liskov:Scientist(name) USING JOIN ON liskov, cs RETURN wing.born AS column