3.7. Execution plans

This section describes operators used as part of an execution plan to execute a query in the Cypher query language.

Neo4j breaks down the work of executing a query into small pieces called operators. Each operator is responsible for a small part of the overall query. The operators are connected together in a pattern called a execution plan.

Each operator is annotated with statistics.

Rows
The number of rows that the operator produced. Only available if the query was profiled.
EstimatedRows
If Neo4j used the cost-based compiler you will see the estimated number of rows that will be produced by the operator. The compiler uses this estimate to choose a suitable execution plan.
DbHits
Each operator will ask the Neo4j storage engine to do work such as retrieving or updating data. A database hit is an abstract unit of this storage engine work.

See Section 3.6.2, “Profiling a query” for how to view the execution plan for your query.

For a deeper understanding of how each operator works, see the relevant section. Operators are grouped into high-level categories. Please remember that the statistics of the actual database where the queries run on will decide the plan used. There is no guarantee that a specific query will always be solved with the same plan.

Execution plan operators at a glance

This table comprises all the execution plan operators ordered lexicographically.

Name Operator type Description

AllNodesScan

Starting point

Reads all nodes from the node store.

AntiConditionalApply

Combining

Checks whether a variable is null, and if so the right-hand side will be executed.

AntiSemiApply

Combining

Tests for the existence of a pattern predicate.

Apply

Combining

Apply works by performing a nested loop.

AssertSameNode

Combining

This operator is used to ensure that no uniqueness constraints are violated.

ConditionalApply

Combining

Checks whether a variable is not null, and if so the right-hand side will be executed.

Constraint operation

Update

Creates a constraint on a (label,property) pair.

CreateNode

Update

Creates a node.

DirectedRelationshipByIdSeek

Starting point

Reads one or more relationships by id from the relationship store.

Distinct

Row

Removes duplicate rows from the incoming stream of rows.

Eager

Row

For isolation purposes, Eager ensures that operations affecting subsequent operations are executed fully for the whole dataset before continuing execution.

EagerAggregation

Row

Eagerly loads underlying results and stores it in a hashmap, using the grouping keys as the keys for the map.

EmptyResult

Update

Eagerly loads everything coming in to the EmptyResult operator and discards it.

Expand(All)

Expand

Given a start node, Expand(All) will follow incoming or outgoing relationships, depending on the pattern relationship.

Expand(Into)

Expand

When both the start and end node have already been found, Expand(Into) is used to find all connecting relationships between the two nodes.

Filter

Row

Filters each row coming from the child operator, only passing through rows that evaluate the predicates to true.

LetAntiSemiApply

Combining

Tests for the absence of a pattern predicate in queries containing multiple pattern predicates.

LetSemiApply

Combining

Tests for the existence of a pattern predicate in queries containing multiple pattern predicates.

Limit

Row

Returns the first 'n' rows from the incoming input.

NodeByIdSeek

Starting point

Reads one or more nodes by id from the node store.

NodeByLabelScan

Starting point

Using the label index, fetches all nodes with a specific label on them from the node label index.

NodeCountFromCountStore

Row

Uses the count store to answer questions about node counts.

NodeHashJoin

Combining

Using a hash table, a NodeHashJoin joins the input coming from the left with the input coming from the right.

NodeIndexContainsScan

Starting point

An index contains scan goes through all values stored in an index, and searches for entries containing a specific string.

NodeIndexScan

Starting point

An index scan goes through all values stored in an index, and can be used to find all nodes with a particular label having a specified property.

NodeIndexSeek

Starting point

Finds nodes using an index seek.

NodeIndexSeekByRange

Starting point

Finds nodes using an index seek where the value of the property matches the given prefix string.

NodeUniqueIndexSeek

Starting point

Finds nodes using an index seek within a unique index.

OptionalExpand(All)

Expand

Traverses relationships from the given node, and ensures that predicates are evaluated before producing rows.

ProcedureCall

Row

Calls a procedure.

Projection

Row

For each row from its input, projection evaluates a set of expressions and produces a row with the results of the expressions.

RelationshipCountFromCountStore

Row

Uses the count store to answer questions about relationship counts.

SelectOrAntiSemiApply

Combining

Tests for the absence of a pattern predicate and evaluates a predicate.

SelectOrSemiApply

Combining

Tests for the existence of a pattern predicate and evaluates a predicate.

SemiApply

Combining

Tests for the existence of a pattern predicate.

Skip

Row

Skips 'n' rows from the incoming rows.

Sort

Row

Sorts rows by a provided key.

Top

Row

Returns the first 'n' rows sorted by a provided key.

Triadic

Combining

Triadic is used to solve triangular queries, such as the very common 'find my friend-of-friends that are not already my friend'.

UndirectedRelationshipByIdSeek

Starting point

Reads one or more relationships by id from the relationship store.

Union

Row

Concatenates the results from the right plan after the results of the left plan.

Unwind

Row

Takes a list of values and returns one row per item in the list.