Skip to content

Commit

Permalink
add note about partitioned operators
Browse files Browse the repository at this point in the history
  • Loading branch information
JPryce-Aklundh committed Jan 23, 2024
1 parent d1a4573 commit 4446344
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions modules/ROOT/pages/planning-and-tuning/runtimes/concepts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ Batch size 128
A key difference between the physical plans produced by the parallel runtime compared to those generated by pipelined runtime is that, in general, more pipelines are produced when using the parallel runtime (in this case, seven instead of the four produced by the same query being run on pipelined runtime).
This is because, when executing a query in the parallel runtime, it is more efficient to have more tasks that can be run in parallel, whereas when running a single-threaded execution in the pipelined runtime it is more efficient to fuse several pipelines together.

Another important difference is that, since the release of Neo4j 5.17, the parallel runtime uses partitioned operators (xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-partitioned-node-by-label-scan[`PartitionedNodeByLabelScan`] in this case).
These operators first segment the retrieved data and then operate on each segment in parallel.

The parallel runtime shares the same architecture as the pipelined runtime, meaning that it will transform the logical plan into the same type of execution graph as described above.
However, when using parallel runtime, each pipeline task can be executed in a separate thread.
Another similarity with pipelined runtime is that queries run on the parallel runtime will begin by generating the first pipeline which eventually will produce a morsel in the input buffer of the subsequent pipeline.
Expand All @@ -331,10 +334,10 @@ Consider the execution graph below, based on the same example query:

image::runtimes_execution_graph2.svg[width="900",role="middle"]

The execution graph shows that execution starts at `pipeline 0`, which consists of the operator `NodeByLabelScan` and can be executed simultaneously on all available threads working on different morsels of data.
The execution graph shows that execution starts at `pipeline 0`, which consists of the operator `PartitionedNodeByLabelScan` and can be executed simultaneously on all available threads working on different morsels of data.
Once pipeline `0` has produced at least one full morsel of data, any thread can then start executing `pipeline 1`, while other threads may continue to execute `pipeline 0`.
More specifically, once there is data from a pipeline, the scheduler can proceed to the next pipeline while concurrently executing earlier pipelines.
In this case, `pipeline 5` ends with an aggregation (performed by the EagerAggregation operator), which means that the last pipeline (6) cannot start until all preceding pipelines are completely finished for all the preceding morsels of data.
In this case, `pipeline 5` ends with an aggregation (performed by the xref:planning-and-tuning/operators/operators-detail.adoc#query-plan-eager-aggregation[`EagerAggregation`] operator), which means that the last pipeline (`6`) cannot start until all preceding pipelines are completely finished for all the preceding morsels of data.

[[runtimes-parallel-runtime-considerations]]
=== Considerations
Expand Down

0 comments on commit 4446344

Please sign in to comment.