9.7. Using

9.7.1. Query using an index hint
9.7.2. Query using multiple index hints
9.7.3. Hinting a label scan

If you do not specify an explicit START clause, Cypher needs to infer where in the graph to start your query. This is done by looking at the WHERE clause and the MATCH clause and using that information to find a useful index.

This index might not be the best choice though — sometimes multiple indexes could be used, and Cypher has picked the wrong one (from a performance point of view).

You can force Cypher to use a specific starting point by using the USING clause. This is called giving Cypher an index hint.

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. It will force Cypher to not use an index that could have been used, and instead do a label scan.

[Note]Note

You cannot use index hints if your query has a START clause.

9.7.1. Query using an index hint

To query using an index hint, use USING INDEX.

Query. 

MATCH (n:Swedish)
USING INDEX n:Swedish(surname)
WHERE n.surname = 'Taylor'
RETURN n

The query result is returned as usual.

Result

n
1 row

Node[3]{name:"Andres",age:36,awesome:true,surname:"Taylor"}


Try this query live. create (_0 {`name`:"Emil"}) create (_1:`German` {`name`:"Stefan", `surname`:"Plantikow"}) create (_2 {`age`:34, `name`:"Peter"}) create (_3:`Swedish` {`age`:36, `awesome`:true, `name`:"Andres", `surname`:"Taylor"}) create _0-[:`KNOWS`]->_2 create _1-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_2 match (n:Swedish) using index n:Swedish(surname) where n.surname = 'Taylor' return n

9.7.2. Query using multiple index hints

To query using multiple index hints, use USING INDEX.

Query. 

MATCH (m:German)-->(n:Swedish)
USING INDEX m:German(surname)
USING INDEX n:Swedish(surname)
WHERE m.surname = 'Plantikow' AND n.surname = 'Taylor'
RETURN m

The query result is returned as usual.

Result

m
1 row

Node[1]{name:"Stefan",surname:"Plantikow"}


Try this query live. create (_0 {`name`:"Emil"}) create (_1:`German` {`name`:"Stefan", `surname`:"Plantikow"}) create (_2 {`age`:34, `name`:"Peter"}) create (_3:`Swedish` {`age`:36, `awesome`:true, `name`:"Andres", `surname`:"Taylor"}) create _0-[:`KNOWS`]->_2 create _1-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_2 match (m:German)-->(n:Swedish) using index m:German(surname) using index n:Swedish(surname) where m.surname = 'Plantikow' and n.surname = 'Taylor' return m

9.7.3. 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 (m:German)
USING SCAN m:German
WHERE m.surname = 'Plantikow'
RETURN m

This query does its work by finding all :German labeled nodes and filtering them by the surname property.

Result

m
1 row

Node[1]{name:"Stefan",surname:"Plantikow"}


Try this query live. create (_0 {`name`:"Emil"}) create (_1:`German` {`name`:"Stefan", `surname`:"Plantikow"}) create (_2 {`age`:34, `name`:"Peter"}) create (_3:`Swedish` {`age`:36, `awesome`:true, `name`:"Andres", `surname`:"Taylor"}) create _0-[:`KNOWS`]->_2 create _1-[:`KNOWS`]->_3 create _3-[:`KNOWS`]->_2 match (m:German) using scan m:German where m.surname = 'Plantikow' return m