Explain and cost
Explain output shows the work that a call completed. The example executes the names query with an explain record and reads its completed stages.
Example
Explain a query
query_text holds this document:
{:find [?name]
:where [[?e "name" ?name]]
:orderBy [?name]}definition := stardust.parse(query_text, .EDN) or_return
defer stardust.close(&definition)
query := stardust.query(db, definition) or_return
defer stardust.close(&query)
result: stardust.Query_Explain
rows := stardust.run(query, explain = &result) or_return
stardust.close(&rows){:value {:load_definition {:cpu 600
:wall 604
:arena_bytes 1680}
:parameters {:cpu 5
:wall 5
:arena_bytes 0}
:run {:cpu 6494
:wall 6531
:arena_bytes 7424}
:total {:cpu 7118
:wall 7160
:arena_bytes 9104}
:arena_capacity 4194304
:work 4169
:rows 3
:compile 111
:plan 234
:execute 0
:group 0
:order 0
:memory_bytes 5995
:memory_refusals 0
:budget_bytes 10489856512
:budget_used_bytes 10194
:budget_peak_bytes 14267
:budget_refusals 0
:retry 0
:stages_completed 3
:retries 0}}Failure output
A failed call can still supply explain output for the stages that completed.
- Read
stages_completed. - Then read the fields of the stages that completed.
The record tables below give the fields, absent values, and time units of each operation.
Stored plan decisions
A call's cost record describes that execution. It does not load stored plan history.
Use the plan operation in Definitions with the explain action to read accepted plans and their history.
Each revision reports its version, source and reason. Trial decisions include candidate proposals and measured verdicts.
Set page_size and max_bytes to bound one diagnostic response.
The response includes the current accepted transaction, the complete plan state and a history page from one snapshot.
Pass a nonzero next_after as the next page's argument.
The adaptive query planner can retry a capped plan with the statistics plan.
Query explain reports those attempts in retry and retries.
cost
This record measures one explain stage. The cpu and wall fields are durations. The ABI gives 100-ns ticks. Thus, a time less than one tick is zero.
| Field | Type | Unit | Range | Absent | Meaning |
|---|---|---|---|---|---|
cpu | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | -1 | Thread CPU time. The call measures this value. Independent calls can differ. |
wall | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | — | Wall time. The call measures this value. Independent calls can differ. |
arena_bytes | builtin.i64 | Bytes | Host type range | — | Bytes the stage allocated from the scratch arena of the call. Heap-owned outputs and the LuaJIT heap are not included. The call measures this value. Independent calls can differ. |
build_explain
This record contains explain output for build.
| Field | Type | Unit | Meaning |
|---|---|---|---|
prepare_expression | Cost | None | — |
compile | Cost | None | — |
total | Cost | None | The cost of all stages. arena_bytes records the peak scratch-arena allocation. |
arena_capacity | builtin.i64 | Bytes | Bytes the scratch arena reserved. The call measures this value. Independent calls can differ. |
stages_completed | u32 | Count | Stages that ran. |
cache_hit | bool | None | The leased runtime holds a compiled copy of the expression. The call measures this value. Independent calls can differ. |
eval_explain
This record contains explain output for evaluate.
| Field | Type | Unit | Meaning |
|---|---|---|---|
prepare_variables | Cost | None | — |
evaluate | Cost | None | — |
adopt_document | Cost | None | — |
total | Cost | None | The cost of all stages. arena_bytes records the peak scratch-arena allocation. |
arena_capacity | builtin.i64 | Bytes | Bytes the scratch arena reserved. The call measures this value. Independent calls can differ. |
document_bytes | builtin.i64 | Bytes | Used bytes of the native value, string and source buffers of the result. The call measures this value. Independent calls can differ. |
stages_completed | u32 | Count | Stages that ran. |
query_explain
This record contains explain output for query run. The compile, plan, execute, group and order fields divide the wall time of run into stages.
| Field | Type | Unit | Range | Meaning |
|---|---|---|---|---|
load_definition | Cost | None | Host type range | — |
parameters | Cost | None | Host type range | — |
run | Cost | None | Host type range | Planning, execution and aggregation. Pages render later, in next. |
total | Cost | None | Host type range | The cost of all stages. arena_bytes records the peak scratch-arena allocation. |
arena_capacity | builtin.i64 | Bytes | Host type range | Bytes the scratch arena reserved. The call measures this value. Independent calls can differ. |
work | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | Thread CPU duration consumed by the query. The call measures this value. Independent calls can differ. |
rows | builtin.i64 | Count | Host type range | Result rows. |
compile | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | The call measures this value. Independent calls can differ. |
plan | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | The call measures this value. Independent calls can differ. |
execute | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | Production of solutions. A streamed result produces solutions while pages render. Thus, execute measures only the solutions that run reads. The call measures this value. Independent calls can differ. |
group | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | Aggregates, windows and computed columns. The call measures this value. Independent calls can differ. |
order | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | The call measures this value. Independent calls can differ. |
memory_bytes | builtin.i64 | Bytes | Host type range | The most working memory the run held reserved in the database's memory budget at once. The call measures this value. Independent calls can differ. |
memory_refusals | builtin.i64 | Count | Host type range | Reservations of the run that the memory budget granted less than asked. The call measures this value. Independent calls can differ. |
budget_bytes | builtin.i64 | Bytes | Host type range | The database's memory budget (memory_budget_bytes). |
budget_used_bytes | builtin.i64 | Bytes | Host type range | Bytes every query of the database held reserved when run returned. The call measures this value. Independent calls can differ. |
budget_peak_bytes | builtin.i64 | Bytes | Host type range | The most bytes the database's queries held reserved at once since it opened. The call measures this value. Independent calls can differ. |
budget_refusals | builtin.i64 | Count | Host type range | Reservations the database's budget granted less than asked since it opened. The call measures this value. Independent calls can differ. |
retry | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | Thread CPU duration of the attempts given up because the planner's plan passed its cap. work includes it. The call measures this value. Independent calls can differ. |
stages_completed | u32 | Count | Host type range | Stages that ran. |
retries | u32 | Count | Host type range | Attempts given up because the planner's plan passed its cap; the query then ran the statistics' plan within the rest of its budget. |
mutation_explain
This record contains explain output for mutation run.
| Field | Type | Unit | Meaning |
|---|---|---|---|
load_definition | Cost | None | — |
parameters | Cost | None | — |
run | Cost | None | — |
total | Cost | None | The cost of all stages. arena_bytes records the peak scratch-arena allocation. |
arena_capacity | builtin.i64 | Bytes | Bytes the scratch arena reserved. The call measures this value. Independent calls can differ. |
stages_completed | u32 | Count | Stages that ran. |
attempts | u32 | Count | Evaluations. More than one when a concurrent write forced a retry. |
patch_explain
This record contains explain output for merge_patch.
| Field | Type | Unit | Meaning |
|---|---|---|---|
copy_patch | Cost | None | — |
commit | Cost | None | Validation and the commit. |
total | Cost | None | The cost of all stages. arena_bytes records the peak scratch-arena allocation. |
arena_capacity | builtin.i64 | Bytes | Bytes the scratch arena reserved. The call measures this value. Independent calls can differ. |
stages_completed | u32 | Count | Stages that ran. |
Explain examples
The generator captured each result from the native library.
Inspect one measured cost stage
expression_text holds this document:
["+" ?x 1]expression := stardust.parse(expression_text, .EDN) or_return
defer stardust.close(&expression)
explain: stardust.Build_Explain
program := stardust.build(expression, &explain) or_return
defer stardust.close(&program)
result := explain.total{:value {:cpu 18
:wall 18
:arena_bytes 0}}Explain expression compilation
expression_text holds this document:
["+" ?x 1]expression := stardust.parse(expression_text, .EDN) or_return
defer stardust.close(&expression)
explain: stardust.Build_Explain
program := stardust.build(expression, &explain) or_return
defer stardust.close(&program)
result := explain{:value {:prepare_expression {:cpu 4
:wall 4
:arena_bytes 0}
:compile {:cpu 11
:wall 11
:arena_bytes 0}
:total {:cpu 18
:wall 19
:arena_bytes 0}
:arena_capacity 65536
:stages_completed 2
:cache_hit true}}Explain patch validation and commit
seed_text holds this document:
{:#_ada {:name "Ada"
:role "engineer"
:age 36}
:#_bob {:name "Bob"
:role "engineer"
:age 41
:mentor {:#link "#_ada"}}
:#_cy {:name "Cy"
:role "designer"
:age 29}
:#_tx {:author "smoke"
:reason "seed"}}patch := stardust.parse(seed_text, .EDN) or_return
defer stardust.close(&patch)
explain: stardust.Patch_Explain
commit := stardust.merge_patch(db, patch, &explain) or_return
defer stardust.close(&commit)
result := explain{:value {:copy_patch {:cpu 1217
:wall 1221
:arena_bytes 3096}
:commit {:cpu 404
:wall 47083
:arena_bytes 8008}
:total {:cpu 1754
:wall 48443
:arena_bytes 11118}
:arena_capacity 4194304
:stages_completed 2}}Explain mutation execution
birthday_text holds this document:
{:query {:find [?e]
:where [[?e "name" "Ada"]]}
:patch {:?e {:age 37}}}source := stardust.parse(birthday_text, .EDN) or_return
defer stardust.close(&source)
mutation := stardust.mutation(db, source) or_return
defer stardust.close(&mutation)
explain: stardust.Mutation_Explain
commit := stardust.run(mutation, explain = &explain) or_return
defer stardust.close(&commit)
result := explain{:value {:load_definition {:cpu 1204
:wall 1211
:arena_bytes 2320}
:parameters {:cpu 13
:wall 14
:arena_bytes 0}
:run {:cpu 8062
:wall 53287
:arena_bytes 43856}
:total {:cpu 9377
:wall 54616
:arena_bytes 46176}
:arena_capacity 4194304
:stages_completed 3
:attempts 1}}Explain expression evaluation
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}expression := stardust.parse(expression_text, .EDN) or_return
defer stardust.close(&expression)
program := stardust.build(expression) or_return
defer stardust.close(&program)
input := stardust.parse(input_text, .EDN) or_return
defer stardust.close(&input)
explain: stardust.Eval_Explain
output := stardust.evaluate(program, input, &explain) or_return
defer stardust.close(&output)
result := explain{:value {:prepare_variables {:cpu 3
:wall 5
:arena_bytes 0}
:evaluate {:cpu 47
:wall 47
:arena_bytes 0}
:adopt_document {:cpu 3
:wall 3
:arena_bytes 0}
:total {:cpu 57
:wall 59
:arena_bytes 0}
:arena_capacity 65536
:document_bytes 42
:stages_completed 3}}Explain query execution
query_text holds this document:
{:find [?name]
:where [[?e "name" ?name]]
:orderBy [?name]}definition := stardust.parse(query_text, .EDN) or_return
defer stardust.close(&definition)
query := stardust.query(db, definition) or_return
defer stardust.close(&query)
explain: stardust.Query_Explain
rows := stardust.run(query, explain = &explain) or_return
defer stardust.close(&rows)
result := explain{:value {:load_definition {:cpu 550
:wall 555
:arena_bytes 1680}
:parameters {:cpu 7
:wall 9
:arena_bytes 0}
:run {:cpu 8737
:wall 8761
:arena_bytes 7424}
:total {:cpu 9318
:wall 9348
:arena_bytes 9104}
:arena_capacity 4194304
:work 5773
:rows 3
:compile 232
:plan 426
:execute 0
:group 0
:order 0
:memory_bytes 5995
:memory_refusals 0
:budget_bytes 10489856512
:budget_used_bytes 10194
:budget_peak_bytes 14267
:budget_refusals 0
:retry 0
:stages_completed 3
:retries 0}}