Skip to content

Commit

Permalink
Add Performance caveats section to Merge/Match dynamic labels section (
Browse files Browse the repository at this point in the history
  • Loading branch information
JPryce-Aklundh authored Dec 19, 2024
1 parent 49d4013 commit 87dc968
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
5 changes: 5 additions & 0 deletions modules/ROOT/pages/clauses/load-csv.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ RETURN n AS bandNodes
Added 4 nodes, Set 4 properties, Added 4 labels
|===

[NOTE]
`MERGE` queries using dynamic values may not be as performant as those using static values.
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.
For more information, see xref:clauses/merge.adoc#dynamic-merge-caveats[`MERGE` using dynamic node labels and relationship types -> Performance caveats].

=== Import compressed CSV files

`LOAD CSV` can read local CSV files compressed with ZIP or gzip.
Expand Down
12 changes: 8 additions & 4 deletions modules/ROOT/pages/clauses/match.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -532,10 +532,6 @@ The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT N
If you use a `LIST<STRING>` with more than one item in a relationship pattern with dynamic relationship types, no results will be returned.
This is because a relationship can only have exactly one type.

[NOTE]
Queries using dynamic values may not be as performant as those using static values.
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.

.Match labels dynamically
[source, cypher]
----
Expand Down Expand Up @@ -630,3 +626,11 @@ RETURN relationshipType, count(r) AS relationshipCount
2+d|Rows: 2
|===

[[dynamic-match-caveats]]
=== Performance caveats

`MATCH` queries using dynamic values may not be as performant as those using static values.
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.

As a result, `MATCH` queries using dynamic values cannot leverage xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead use 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.

48 changes: 43 additions & 5 deletions modules/ROOT/pages/clauses/merge.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -703,10 +703,6 @@ The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT N
Using a `LIST<STRING>` with more than one item when merging a relationship using dynamic relationship types will fail.
This is because a relationship can only have exactly one type.

[NOTE]
Queries using dynamic values may not be as performant as those using static values.
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.

.Parameters
[source, parameters]
----
Expand All @@ -730,7 +726,7 @@ RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collec
// end::clauses_merge_dynamic_merge[]

.Result
[role="queryresult",options="footer",cols="3*<m"]
[role="queryresult",options="footer",cols="4*<m"]
|===
| name | labels | relType | movies

Expand All @@ -742,3 +738,45 @@ RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collec
4+d|Rows: 1 +
|===

[[dynamic-merge-caveats]]
=== Performance caveats

`MERGE` queries that use dynamic values may not be as performant as those using static values.
This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.

As a result, `MERGE` queries with dynamic values cannot leverage xref:planning-and-tuning/operators/operators-detail.adoc#leaf-operators[index scans or seeks] and must instead use 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.

To circumvent possible performance issues, place the dynamic labels or relationship types within `ON CREATE` or `ON MATCH` subclauses.

.Parameters
[source, parameters]
----
{
"onMatchLabels": ["Filmmaker", "AwardRecipient"],
"onCreateLabels": ["ScreenWriter", "AwardWinner"]
}
----

.Merge nodes using dynamic values in `ON CREATE` and `ON MATCH` subclauses
[source, cypher]
----
MERGE (n:Person {name: "Greta Gerwig"})
ON MATCH
SET n:$($onMatchLabels)
ON CREATE
SET n:$($onCreateLabels)
RETURN labels(n) AS gretaLabels
----

Because a `Person` node with the `name` "Greta Gerwig" already exists, this query will only `SET` the dynamic labels added to the `ON MATCH` subclause.

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
| gretaLabels

| ["Person", "Director", "Filmmaker", "AwardRecipient"]

1+d|Rows: 1
|===

0 comments on commit 87dc968

Please sign in to comment.