How queries work

EXPLAIN queries

The EXPLAIN clause lets users inspect the plans of their queries.

EXPLAIN queries start out by parsing the inner query (what’s inside the EXPLAIN clause) and getting the query plan, which is a tree of logical operators. These steps use existing methods described in Lexical and Syntactic Analysis, Semantic Analysis and Symbol Generation and Planning.

With the plan made, the interpreter moves on to generating the output. The plan::PrettyPrint function creates a hierarchical visitor (PlanPrinter) that goes through the plan. PlanPrinter contains a visit function for each operator. Visit functions make the output for the current operator and call the accept function of its child operator(s) so that plan traversal can continue.

PROFILE queries

The PROFILE clause creates a detailed report about the execution of the query plan, with time and hits statistics for each operator.

Compared to EXPLAIN, there are similarities and differences in the output:

The first steps are as in [EXPLAIN queries start out by parsing the inner query (what’s inside the EXPLAIN clause) and getting the query plan, which is a tree of logical operators. These steps use existing methods described in Lexical and Syntactic Analysis, Semantic Analysis and Symbol Generation and Planning.](https://memgraph.notion.site/EXPLAIN-queries-start-out-by-parsing-the-inner-query-what-s-inside-the-EXPLAIN-clause-and-getting--f7da3f9f63824619a4167326f11a20d7) and result in the inner query plan.

With the plan made, the interpreter creates a PullPlan (and thus a cursor) and starts pulling from the cursor. Each operator’s cursor has a SCOPED_PROFILE_OP call that executes on pull.

These calls are the key part:

  1. They create profiling stats
  2. They create a tree of ProfilingStats nodes that corresponds to the plan tree

In short, the above means that an operator tree with profiling statistics for each operator is constructed during query execution.

Next, the interpreter switches to ProfilingStatsWithTotalTime (to get absolute time data) and traverses the operator tree to create the output table (ProfilingStatsToTableHelper::Output). This is recursive DFS that visits children branches and generates their table row before the parent’s table row.

Filtering