Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

Performance tuning

GQL generates an execution plan for each query to determine how to execute the query efficiently. You can view the execution plan to understand how the query is executed and optimize the query performance accordingly.

Execution plan structure

An execution plan of a query consists of a tree of plan nodes, each of which may have zero or more child nodes. To generate an execution plan, the system converts the plan into a set of pipelines. Each pipeline consists of a linear sequence of operators corresponding to a linear sub-tree of the plan. The plan tree is broken down into linear sub-trees by disconnecting all but one child node from each parent node that has two or more children. At runtime, the execution engine schedules execution based on these pipelines.

Query execution process

The following figure illustrates how an execution plan is derived during the execution of a GQL query:

GQL query string  // The query string provided by the user.
      |
      | 
      v
    Parser      // Parses the query string to generate an abstract syntax tree (AST). 
      |
      | 
      v 
    Validator   // Validates the AST to ensure that the query is syntactically and semantically correct.
      |
      | 
      v  
    Planner     // Generates the logical plan of the query.
      |
      | 
      v
    Optimizer   // Optimizes the logical plan to generate the physical plan.
      |
      |
      v
   Execution Engine   // Derives an execution plan and follows it to produce the query result.

Viewing execution plans

When a query is slower than expected, you can use the EXPLAIN or PROFILE command to view the execution plan and identify the bottleneck. A practical workflow is:

  1. Run EXPLAIN to inspect the final plan shape.
  2. Check whether selective filters or starting points appear early enough.
  3. Run PROFILE to inspect actual rows, time, and operator cost.
  4. If the query contains subqueries or is a graph-pattern query, respectively use EXPLAIN DECORRELATED or EXPLAIN CBO to inspect optimization effects. To compare reordered MATCH plans, first enable reordering explicitly with SESSION SET enable_reorder = true or /*+ SET_VAR(enable_reorder=true) */.
  5. If reordering degrades performance after enable_reorder is enabled, consider applying the NO_REORDER hint to enforce a specific expansion order for one path pattern. For more information, see NO_REORDER hint.
  6. If needed, compare with EXPLAIN RAW to see what optimization changed.

When using the ngql CLI, you can also adjust the execution plan style by using the :planstyle command. For more information, see Execution plan style setting in the ngql documentation.