The EXPLAIN statement is used to display the query planner for a following statement.
Available since: v3.0.0
Note
The output for the EXPLAIN statement is for informational purposes and subject to change. Be sure not to develop tools around it that rely on a single predictible output.
The EXPLAIN statement is used to display the query planner for a statement.
Statement syntax
SurrealQL Syntax
EXPLAIN[ ANALYZE ][ FORMAT TEXT | JSON ]@statement
Example usage
An EXPLAIN statement is one that can be appended to another statement that does not modify database resources, i.e. a SELECT statement or another statement that returns a value.
The two main decisions to make when using an EXPLAIN statement are:
Use default text format or add FORMAT JSON to output the format in JSON?
Add the ANALYZE clause after EXPLAIN
The following example shows the four possible types of output when followed by a simple string.
The context field in an EXPLAIN statement refers to the minimum context level for an operation: Rt (root), Ns (namespace), or Db (database) level.
Operator types
The operator field in the output of an EXPLAIN statement is the most relevant area to take note of. Here is a list of many of the operator types you will see in the statement output.
This allows you to get an insight into exactly what sort of work is being performed by the database when a query is executed.
For example, take the following simple example in which one person record has a single friend. The final two queries return the same result, but one is a SELECT...FROM ONLY query while the other is a direct destructuring of the link from its record id.
Here is an example of output for a query of a complexity more similar to those seen in production applications.
EXPLAIN ANALYZESELECT id as commentId, in.id as id, in.creationDate as creationDate FROM is_comment_of WHERE out =media_text_test:0 ANDin.creationDate<d'2026-01-09T00:00:00.000Z' ORDER BY in.creationDate DESC LIMIT 2;
Filtered KNN and the predicate attribute on KnnScan
Available since: v3.1.5
When a K-nearest neighbours search over an indexed vector field is combined with an additional non-KNN condition, the planner pushes that residual condition into the index search. Non-matching candidates are rejected during the graph traversal, before they can occupy one of the K result slots, rather than being filtered out after the neighbours have been retrieved.
This behaviour can be seen by appending the EXPLAIN clause to the end of a query to show its plan. Here, the KnnScan operator surfaces this pushed-down condition as a predicate attribute, in the same way that TableScan exposes its own predicate.
The KnnScan line shows that the index idx_pt is searched for k: 2 neighbours with an exploration factor of ef: 40 (the two values of the <|2,40|> operator), and that the flag = true condition is applied inside the search as a predicate. The same condition also appears on the Filter line above; the difference is that the predicate on KnnScan is what causes non-matching candidates to be discarded during the search rather than only afterwards. Without an extra condition the predicate attribute is absent. DISKANN indexes use the same KnnScan operator and render an identical line.