Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Performance caveats section to Merge/Match dynamic labels section #1137

Merged
merged 2 commits into from
Dec 19, 2024
Merged
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
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
|===

Loading