Skip to main content
Version: v3.x

Hasura Query Plan

The Hasura v3 engine can output the GraphQL execution plan for a given query via the "explain" API.

The execution plan output is represented as a tree of type ExplainStep. You can also visualize the query plan, SQL plan, and SQL query used for each execution by clicking the Explain query button in your GraphiQL's request field:

Explain with sql

ExplainStep

The ExplainStep output can be one of the following:

ExplainStepDescription
ModelSelectA select on the data connector's model
CommandSelectA select on the data connector's command
ForEachA for-each loop on the data returned by the parent step
HashJoinA hash join of the data returned by the steps to construct valid response
SequenceA sequential execution of steps
ParallelA parallel execution of steps

ModelSelect

A ModelSelect step represents fetching data from a Model. This includes fetching across local relationships. For example, the following query's execution plan will be a ModelSelect only:

query LocalRelationship {
cities {
# Backed by a model
code
name
state {
# Local relationship
name
}
}
}
Local relationship

Click here for the API reference of ModelSelect.

CommandSelect

Just like the ModelSelect, a CommandSelect represents fetching data from a Command. Click here for the API reference of CommandSelect.

ForEach

A ForEach step represents fetching data from a DataConnector for each of the data from the parent node. A ForEach will always be present if we need to fetch some additional data (such as from a remote relationship) for the data returned by the parent node. For example, the following query's execution plan will have a ForEach step:

query RemoteRelationship {
cities {
# Backed by a model
code
name
weather {
# Remote relationship
forecast
}
}
}
Remote relationship

HashJoin

A HashJoin step represents joining the data fetched from two different steps. For example, the above query's execution plan will have a HashJoin step for joining the Weather model to City.

Sequence

A Sequence step represents a sequential execution of steps. For example, the following query's execution plan will have a Sequence step (as we need to fetch a Weather instance for each of the City models fetched):

query RemoteRelationship {
cities {
# Backed by a model
code
name
weather {
# Remote relationship
forecast
}
}
}
Remote relationship

Parallel

A Parallel step represents a parallel execution of steps. For example, the following query's execution plan will have a Parallel step (as we can fetch Department and Census in parallel):

query ParallelExecution {
cities {
# Backed by a model
code
name
departments {
# Remote relationship
name
ministers {
name
}
}
census {
# Remote relationship
data
}
}
}
Parallel execution

Example

In the example below, for each user, we are fetching the user's name, their notifications via a local relationship, and their favorite artists from a remote relationship:

query MyQuery {
users {
name
# local relationship
notifications {
id
message
}
# remote relationship
user_to_favorite_artist {
name
}
}
}
Explain plan example

Now, from the explain plan, we can understand that:

  • There are three sequential steps:
    • Make a selection on the users model
    • For each user, make a selection on the artists model
  • HashJoin the users and artists models to construct the response