---
title: "Analyze a SQL query and return optimization suggestions"
method: POST
path: "/v1/query/optimize"
tags: ["query"]
---

# Analyze a SQL query and return optimization suggestions

`POST /v1/query/optimize`

## Request

- Base URL: `https://data.thinair.co`
- URL: `https://data.thinair.co/v1/query/optimize`
- Auth: API key in header `x-api-key`

Run EXPLAIN against the resolved connection — an estimated plan; the query is not executed — parse it, and return ranked recommendations (sequential scans, nested-loop blow-ups, MySQL filesort/temp table, and on SQL Server the optimizer's missing-index statements). Costs 1 quota unit per call. Build tier (or higher) required.

## Request body

- OptimizeRequest: Analyze a SQL query and return optimization suggestions: an estimated EXPLAIN plan summary plus ranked findings and index recommendations. It does not return a rewritten query — `original_query` comes back unchanged. Costs 1 quota unit.
  - `connection` string: Connection name (display) or id (uuid). When omitted, the tenant's default (first added) connection is used. Same fallback as the MCP `optimize_query` tool.
  - `sql` string, required: SQL query to analyze. Read-only (SELECT / WITH / EXPLAIN). The handler runs `EXPLAIN (ANALYZE false, FORMAT JSON)` on Postgres, `EXPLAIN` on MySQL, or `SET SHOWPLAN_XML ON` on SQL Server — an estimated plan in every case, with no execution — and parses it for sequential/table scans, nested-loop joins, and (MySQL) temporary tables and filesorts. Missing-index CREATE statements come from the SQL Server optimizer and are therefore mssql-only. Sort spills are NOT detected on any dialect: a spill is visible only in a plan produced by actually running the query, which this tool never does.
  - `dialect_hint` 'postgres' | 'mysql' | 'mssql': Optional dialect hint. The handler derives the actual dialect from the resolved connection — this hint is informational and reserved for future cross-dialect rewrite support. On SQL Server the handler captures the ESTIMATED plan via SET SHOWPLAN_XML ON/OFF (no query execution) and returns the same recommendation shape as Postgres/MySQL (scans, missing indexes, expensive operators).

## Response `200`

Plan analysis. `data.recommendations` lists issues; empty + `data.verdict: 'efficient'` when nothing actionable was found.

- OptimizeResponse: EXPLAIN-plan analysis result. `data.recommendations[]` lists each issue (sequential scan, missing index, filesort, …) with severity and a suggestion. `data.plan` includes the raw plan text only when recommendations exist; clean plans return `data.verdict: 'efficient'` plus a node-type summary instead. Mirrors the MCP `optimize_query` tool output.
  - `data` object, required
  - `display` object, required
  - `summary` string
  - `insights` object[]
  - `meta` object, required

## Other responses

- `400`: Invalid request body or unparseable SQL.
- `401`: Authentication required or failed.
- `403`: Tier gate — requires Build plan or higher (caller is on Discover).
- `404`: Connection not found, or the tenant has no connections registered.
- `429`: Quota exceeded for this tenant.
- `502`: Upstream database unreachable (network, TLS, DNS) — no quota debited.
- `503`: Pool saturated or circuit breaker open — no quota debited.

---

[API](https://skmtc.dev/thinair/apis/thinair-data-api.md) · [All operations](https://skmtc.dev/thinair/apis/thinair-data-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thinair/apis/thinair-data-api/revisions/8a2a2d1b2400?raw)
