Adaptive query planner

The adaptive_query_planner plugin learns from query and mutation selections. It compares alternative join plans in the background and stores accepted plans with their definitions. Applications use the same query and mutation operations with or without the plugin.

Enable the planner

Install the plugin library beside the core library, as described in Plugin installation. Include this entry in the plugins open option:

dust26 B
adaptive_query_planner {}

This selection enables only the adaptive planner. Include other required plugins in the same object. An absent selection enables no plugins. The planner has no plugin dependencies. The selection lasts until the database closes. To change it, close and reopen the database.

Settings

The settings object accepts one member:

SettingDefaultAccepted valuesEffect
memoryShare0.015625 (1/64)A number greater than zero and at most oneBounds retained planner state and each trial's memory allowance

For example, select a share of 1/32 with:

dust45 B
adaptive_query_planner {memoryShare 0.03125}

The share uses the database's memory_budget_bytes setting. It does not increase that budget. With a 256 MiB database budget, the default share is 4 MiB. Each trial has a separate memory allowance within the database budget. Shared caches do not use the trial allowance. Reservations can receive less when other work holds memory. Limited capacity reduces retained evidence and pending trials. Unknown settings, nonnumeric values, zero, negative values and values greater than one fail database open with invalid_argument.

Learning and plan selection

The core planner can choose join orders and hash joins from database statistics without this plugin. The plugin also records per-step row counts and compares them with estimates. It distinguishes exact counts from bounds produced by limits, early close, cancellation and incomplete execution. For parameterized definitions, exact typed tuples can retain separate plans and observations. Values without a retained plan share one fallback. Measured foreground demand and repeated-run savings must repay lookup, trial and storage costs. Retained state stays within its memory share. New values cannot evict a context with greater measured benefit.

Inline queries can use learned evidence. Background plan trials and persisted accepted plans belong to stored query and mutation definitions. Mutation feedback measures selection only. Trials never apply mutation patches. Queries with temporal clauses bypass adaptive planning.

A stored query normally runs its accepted plan while a trial compares alternatives. Changes in field counts or observed rows can trigger another comparison. The statistics plan can run while that comparison finishes. Timing noise determines whether the evidence supports a change. A noisy query can need more runs before a decision.

Background trials

Trials run at the lowest priority on the shared work pool. They consume CPU and memory in addition to application queries. The planner alternates candidate plans on the same database snapshot and checks their results before accepting a faster plan. Trials use the parameter values of the run that requested them. Comparisons across different snapshots are discarded. A promoted plan remains under observation and can be reverted if foreground measurements show a slowdown beyond measured noise. Closing the database cancels its pending planner work.

Candidate strategies propose plans from learned evidence and database statistics. Optional native anchor probes run when measured estimation-error costs justify their CPU allowance. Probes use the trial's snapshot and bindings, honor cancellation and check memory allocations. An interrupted prefix is a lower bound. It cannot prove that a query is empty. The candidate stages are internal extension points. Applications cannot register stages through the C ABI or bindings.

Synchronization

Queries can run while background trials compare plans. Applications do not need a sync call for correct query results. This plugin provides no sync operation. A plugin_call of sync on "adaptive_query_planner" reports invalid_argument with code unknown_operation. Later queries can use an improved plan after a trial finishes.

Stored plans and restart

Accepted plans are stored in the protected stardust/plan field on the entity of the stored query or mutation. A plan records its clause order, hash choices, definition revision and the field counts used when it was accepted. Each plan change is a transaction in the definition's history. It does not edit the authored query or trigger index reconciliation. Automatic writes check that the definition and current plan still match the state used for the decision.

Stored plans survive database close and can run when the database reopens without the plugin. Learned row counts, corrections and timing samples stay in memory and are collected again after restart. A valid pinned plan is never replaced automatically, including after data changes. Use the core plan operation to pin, unpin, replan or revert a stored definition. A global pin protects every parameter value. Replan clears specialized contexts and preserves the global pin. Revert restores a complete historical bundle, including its contexts and pin. Explicit changes compare the authored revision and accepted plan transaction inside the commit. The operation also works without this plugin. See Definitions.

Explain and query limits

Request query explain output through the normal query run options. The retry and retries fields report attempts abandoned after an adaptive plan exceeded its internal execution cap. The query then uses the statistics plan within the remaining budget. The work field includes CPU time spent on abandoned attempts. The caller's cost ceiling and the query's maxCost and maxWorkRows limits apply across all attempts. Cost records describe the current run. Use the plan operation with the explain action for the current accepted bundle and paged revision history. Each revision includes its source and reason. Trial reasons report candidate proposals and measured verdicts. Set the diagnostic page size and buffer capacity for each call. Stored history has no fixed revision cutoff.

Without the plugin

Query and mutation selections use core statistics and valid stored plans. When field counts change, the core compares an unpinned stored plan with the statistics plan. It keeps the stored plan unless the statistics plan is cheaper beyond the estimate uncertainty. A missing or inapplicable plan uses statistics. A damaged stored plan reports an error. The database does not collect adaptive evidence, run adaptive trials or automatically persist adaptive plan improvements.