SapixDBSapixDB/Docs
Home

Query

Query Explain

The explain query type returns the execution plan the engine would use for a given filter — without actually running the query. Use it to verify index selection, diagnose unexpected full scans, and confirm that a newly created index is active before relying on it in production.

explain does not execute the queryAn explain request reads only index metadata. It touches zero strand records and returns in microseconds. It is completely safe to run on a production agent at any time.

Request Shape

Send a POST to the query endpoint with "type": "explain" instead of "type": "scan". Pass the same filter you intend to run. No limit or offset is needed — they are ignored for explain requests.

HTTP
POST /v1/agents/:id/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type":   "explain",
  "filter": { ... }
}

Example — Checking a Single-Field Filter

Request
POST /v1/agents/users/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type":   "explain",
  "filter": {
    "field": "plan",
    "op":    "eq",
    "value": "pro"
  }
}

Response when an index is available

Response — index_scan
{
  "explain": {
    "strategy": "index_scan",
    "index":    "idx_plan",
    "hint":     "Single-field index on 'plan' — expected O(k) where k = matching records"
  }
}

Response when no index is available

Response — full_scan
{
  "explain": {
    "strategy": "full_scan",
    "index":    null,
    "hint":     "No index found for field 'plan' — full strand scan"
  }
}

Response Fields

FieldTypeDescription
strategystringEither index_scan or full_scan. See Strategy Types below.
indexstring | nullThe name of the index that will be used, or null for a full scan.
hintstringA human-readable description of the chosen strategy including complexity estimate.

Strategy Types

index_scan

The engine found an index that covers the filter. Query cost is O(k) where k is the number of records matching the filter — not the total number of records in the strand. This is the fast path. The index field names the specific index chosen (single-field, composite, or FTS).

full_scan

No usable index was found. The engine will read every record in the strand and evaluate the filter in memory. Cost is O(n) where n is the total number of records. For large strands this can be slow. The index field is null.

full_scan is not always badFor a strand with fewer than a few thousand records, a full scan is typically fast enough. Only invest in index creation when the explain shows full_scan on a strand you expect to grow or on a hot query path with latency requirements.

Recommended Workflow

Use explain as part of your standard index management cycle:

1
Run explain on your query
Send the filter you plan to use in production and check the strategy. If it shows index_scan with the expected index, you are done.
2
Create an index if needed
If explain shows full_scan and the strand is large, create a single-field, composite, or FTS index for the filtered field(s).
3
Wait for the index to become ready
Poll GET /v1/agents/:id/indexes until the new index shows status: ready. The build is asynchronous.
4
Re-run explain to verify
Send the same explain request again. The response should now show index_scan with the new index name.
Step 1 — explain shows full_scan
POST /v1/agents/users/query
{ "type": "explain", "filter": { "field": "plan", "op": "eq", "value": "pro" } }

// Response:
{ "explain": { "strategy": "full_scan", "index": null, "hint": "No index found for field 'plan' — full strand scan" } }
Step 2 — create the index
POST /v1/agents/users/indexes
{ "name": "idx_plan", "field": "plan" }
Step 3 — wait for ready
GET /v1/agents/users/indexes

// Response when ready:
{ "indexes": [{ "name": "idx_plan", "field": "plan", "type": "single", "status": "ready" }] }
Step 4 — re-explain confirms index_scan
POST /v1/agents/users/query
{ "type": "explain", "filter": { "field": "plan", "op": "eq", "value": "pro" } }

// Response:
{ "explain": { "strategy": "index_scan", "index": "idx_plan", "hint": "Single-field index on 'plan' — expected O(k) where k = matching records" } }

Explain with Compound Filters

Explain works with any filter shape, including AND and OR blocks. For compound filters the engine reports the strategy it will use for the dominant (most selective) branch.

Explain a composite-index query
POST /v1/agents/users/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type": "explain",
  "filter": {
    "AND": [
      { "field": "plan",    "op": "eq", "value": "pro" },
      { "field": "country", "op": "eq", "value": "US"  }
    ]
  }
}

// Response when composite index exists:
{
  "explain": {
    "strategy": "index_scan",
    "index":    "idx_plan_country",
    "hint":     "Composite index on ['plan','country'] — expected O(k) where k = matching records"
  }
}

Explain with FTS Filters

Explain an FTS query
POST /v1/agents/articles/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type": "explain",
  "filter": {
    "field": "content",
    "op":    "fts",
    "value": "cryptographic signing"
  }
}

// Response when FTS index exists:
{
  "explain": {
    "strategy": "index_scan",
    "index":    "idx_fts_content",
    "hint":     "FTS index on 'content' — posting-list intersection for 2 query token(s)"
  }
}
Related pagesSingle-Field Indexes — create indexes that turn full scans into index scans. Composite Indexes — multi-field indexes for AND filters. Full-Text Search — FTS indexes for keyword queries.