# Using indexed nodes and simple queries my cypher queries are still taking around 500ms. Can this be further optimized? Looking for advice

**URL:** <https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615>\
**Category:** Cypher\
**Tags:** performance, cypher\
**Created:** [December 18, 2020, 5:48pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615 "2020-12-18T17:48:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sl77](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/sl77/32/15605_2.png) [@sl77](https://community.neo4j.com/u/sl77)\
**Post date:** [December 18, 2020, 5:48pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/1 "2020-12-18T17:48:22Z")

</div>

Here is the simple query I am running that serves as the base for more complex queries. I am trying to optimize these queries to run faster, but am hitting a wall when even this simple query is running at 500ms. I dont understand how to make this query any more bare bones, but perhaps there is something I am missing or another way I can write it? Here is the query:

```auto
explain MATCH (o:Order)-[:CONTAINS_PRODUCT]->(p) 
WHERE o.accountGUID = 'xxxxxxxxxxxxxxx' AND p.id IN ['4753230364775'] AND o.createdAt >= 1576775048 
return o, p LIMIT 10

```

With results as

```auto
Started streaming 10 records after 502 ms and completed after 515 ms.

```

Or when profiling around 600ms.

I understand it is the p.id check that is taking the longest as it has to sort through all products attached to each order to find orders that contain that product until it hits the limit, but am not sure how to make that any faster. For example running

```auto
MATCH (o:Order)-[:CONTAINS_PRODUCT]->(p) 
WHERE o.accountGUID = 'xxxxxxxxxxxxxxx' AND o.createdAt >= 1576775048 
return o, p LIMIT 10

```

Completes in less than 1ms

 ![Screen Shot 2020-12-18 at 11.35.36 AM](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/2X/9/9d85df1cfb300c267a80dfb4f76a643277b2eb5c.png)  
 ![Screen Shot 2020-12-18 at 11.38.53 AM](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/2X/2/23d259afe20d4f04ae09c0b3fcb1c7081a8b6170.png)

Any advice would be appreciated.

---

<div class="post-metadata">

**Author:** ![clem](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/clem/32/4364_2.png) [@clem](https://community.neo4j.com/u/clem)\
**Post date:** [December 18, 2020, 6:00pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/2 "2020-12-18T18:00:49Z")

</div>

One clever thing you can do, is move `LIMIT` before the `RETURN` statement. Otherwise, the query creates a huge list, only to trim it to 10 entries. (This isn't obvious.)

See: [5 Secrets to More Effective Neo4j 2.2 Query Tuning - Neo4j Graph Data Platform](https://neo4j.com/blog/neo4j-2-2-query-tuning/)

---

<div class="post-metadata">

**Author:** ![andrew\_bowman](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/andrew_bowman/32/73_2.png) [@andrew\_bowman](https://community.neo4j.com/u/andrew_bowman)\
**Post date:** [December 18, 2020, 8:08pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/3 "2020-12-18T20:08:46Z")

</div>

What label is on `p`? :Product? If so, is there a unique constraint on :Product(id)? If so we may be able to optimize this a bit:

```auto
MATCH (o:Order), (p:Product)
WHERE o.accountGUID = 'xxxxxxxxxxxxxxx' AND p.id IN ['4753230364775'] AND o.createdAt >= 1576775048 
MATCH (o:Order)-[:CONTAINS_PRODUCT]->(p1) 
WHERE p1 = p
RETURN o, p
LIMIT 10

```

This is assuming :Product(id) is unique. It should pre-match the nodes, then perform the expansion, and instead of having to do property checking on `p` to see if it's the right product, it will compare the nodes themselves, which is more efficient (it's basically comparing the internal graph ids, which should be fast).

You could also try adding a composite index on `:Order(accountGUID, createdAt)`.

---

<div class="post-metadata">

**Author:** ![sl77](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/sl77/32/15605_2.png) [@sl77](https://community.neo4j.com/u/sl77)\
**Post date:** [December 18, 2020, 9:19pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/4 "2020-12-18T21:19:47Z")

</div>

Thank you Andrew that is very helpful! Yes (p) is :Product and has a uniqueness constraint on id.

Using your advice and the other user who commented on limiting WITH statement I was able to significantly speed up my queries.

However I am facing another confusing issue dealing with indexed searching i was hoping you could help with?

My queries for :Session nodes are taking extremely long, like 25 seconds or more, despite the fact they they are indexed. When I use the explain or Profile planners I can see that these are taking so long because they are scanning by label rather than using the indexes I have. Could you possibly explain why this is happening?

Here is the query:

```auto
MATCH (n:Session) where n.accountGUID = 'xxxxxxxxxxxxxxx' 
RETURN n LIMIT 25

```

It takes 25+ seconds  
I have attached a picture of the EXPLAIN plan.

Using :schema in the cypher terminal i can see that is is Indexed:

```auto
ON :Session(accountGUID, profileGUID, sessionKey) ONLINE (for uniqueness constraint)

```

And here are the constaints:

```auto
ON ( session:Session ) ASSERT (session.accountGUID, session.profileGUID, session.sessionKey) IS NODE KEY

```

Does this mean I have to provide all 3, accountGUID, profileGUID, and sessionKey? All my other nodes are Indexed with accountGUID and ID, but i can use one or the other to search by index, so im wondering what the case is here.

Very much appreciate the help!

 ![Screen Shot 2020-12-18 at 3.15.59 PM](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/2X/f/f149a8a285744f03bd646617ce8a2d409b20cc5a.png)

---

<div class="post-metadata">

**Author:** ![andrew\_bowman](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/andrew_bowman/32/73_2.png) [@andrew\_bowman](https://community.neo4j.com/u/andrew_bowman)\
**Post date:** [December 18, 2020, 9:22pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/5 "2020-12-18T21:22:54Z")

</div>

You're correct, when there is a composite index (on its own or because of a node key constraint) all indexed properties must be present for the index to be leveraged. You would have to create an index or unique constraint on :Session(accountGUID) in order to use the index when only accountGUID is used for lookup.

---

<div class="post-metadata">

**Author:** ![sl77](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/sl77/32/15605_2.png) [@sl77](https://community.neo4j.com/u/sl77)\
**Post date:** [December 18, 2020, 9:29pm UTC](https://community.neo4j.com/t/using-indexed-nodes-and-simple-queries-my-cypher-queries-are-still-taking-around-500ms-can-this-be-further-optimized-looking-for-advice/30615/6 "2020-12-18T21:29:35Z")

</div>

Thanks so much! Appreciate the help!
