Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions modules/ROOT/pages/clauses/match.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -649,15 +649,33 @@ The table below outlines performance caveats for specific Neo4j versions.
| Neo4j versions | Performance caveat

| 5.26 -- 2025.07
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.

| 2025.08 -- current
| 2025.08 -- 2025.10
| The Cypher planner is able to leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically.
This is enabled by the introduction of three new query plan operators:
xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-label-node-lookup[`DynamicLabelNodeLookup`], xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-directed-relationship-type-lookup[`DynamicDirectedRelationshipTypeLookup`], and xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-undirected-relationship-type-lookup[`DynamicUndirectedRelationshipTypeLookup`].
It is not, however, able to use indexes on property values.
For example, `MATCH (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicLabelNodeLookup` on `$(label)`.

| 2025.11 -- current
a| The Cypher planner is able to leverage indexes on property values, however:

* It only supports exact seeks on range indexes (no full text or spatial).
* The index order cannot be leveraged, so the planner must insert separate ordering if required later on in the query.
* Parallel runtime seeks and scans are single-threaded.
* The planner doesn't combine multiple property index seeks when generating the results for the dynamic part of the query. For example, using `$any` in combination with multiple labels that share an index on a property result in the operator choosing one of the indexes based on selectivity and then stepping through the seek results and filtering for the remainder of the expression.
+ Example:
+
[source, cypher, role=test-skip]
----
CREATE RANGE INDEX actor_has_birthyear FOR (a:Actor) ON (a.birthYear)
CREATE RANGE INDEX director_has_birthyear FOR (d:Director) ON (d.birthYear)

// The below MATCH can leverage one of the indexes, but not both
MATCH (p:$any(["Actor", "Director"]) { birthYear: 1983 }) RETURN p.name
----

|===

[[further-reading]]
Expand Down
11 changes: 9 additions & 2 deletions modules/ROOT/pages/clauses/merge.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -750,13 +750,20 @@ The table below outlines performance caveats for specific Neo4j versions.
| Neo4j versions | Performance caveat

| 5.26 -- 2025.07
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.
| The xref:planning-and-tuning/execution-plans.adoc[Cypher planner] is not able to leverage xref:indexes/search-performance-indexes/index.adoc[indexes] with xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead utilize the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-all-nodes-scan[`AllNodesScan`] operator, which reads all nodes from the node store and is therefore more costly.

| 2025.08 -- current
| 2025.08 -- 2025.10
| The Cypher planner is able to leverage xref:indexes/search-performance-indexes/using-indexes.adoc#token-lookup-indexes[token lookup indexes] when matching node labels and relationship types dynamically.
This is enabled by the introduction of three new query plan operators:
xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-label-node-lookup[`DynamicLabelNodeLookup`], xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-directed-relationship-type-lookup[`DynamicDirectedRelationshipTypeLookup`], and xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-dynamic-undirected-relationship-type-lookup[`DynamicUndirectedRelationshipTypeLookup`].
It is not, however, able to use indexes on property values.
For example, `MERGE (n:$(Label) {foo: bar})` will not use any indexes on `n.foo` but can use a `DynamicLabelNodeLookup` on `$(label)`.

| 2025.11 -- current
a| The Cypher planner is able to leverage indexes on property values, however:

* It only supports exact seeks on range indexes (no full text or spatial).
* The index order cannot be leveraged, so the planner must insert separate ordering if required later on in the query.
* Parallel runtime seeks and scans are single-threaded.

|===
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,33 @@ a| Both are similar to the `Merge` operator, but:
* xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-merge-into[`MergeInto`] is used when the start and end node of the pattern is matched outside the `MERGE` pattern;
* xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-merge-unique-node[`MergeUniqueNode`] is used when there is a property uniqueness constraint on the property used in the `MERGE` statement.

a|
label:functionality[]
label:updated[]

[source, csv]
----
// people.csv
label,name
Actor,Henry Cavill
----

[source, cypher, role=test-skip]
----
CREATE RANGE INDEX actor_has_name FOR (a:Actor) ON (a.name);

LOAD CSV WITH HEADERS FROM 'people.csv' AS row
// The MERGE below can leverage the index to check for existence before a CREATE
MERGE (:$(row.label) { name: row.name })
----

a| Cypher can now leverage indexes on property values, improving the performance of xref:clauses/match.adoc#dynamic-match-caveats[`MATCH`] and xref:clauses/merge.adoc#dynamic-merge-caveats[`MERGE`] when doing so, however:

* It only supports exact seeks on range indexes (no full text or spatial).
* The index order cannot be leveraged, so the planner must insert separate ordering if required later on in the query.
* Parallel runtime seeks and scans are single-threaded.
* The planner doesn't combine multiple property index seeks when generating the results for the dynamic part of the query.

|===


Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.