Skip to main content
The EXPLAIN statement displays information about how Turso executes a SQL statement without actually running it. There are two forms: EXPLAIN shows the virtual machine bytecode, and EXPLAIN QUERY PLAN shows the high-level query execution strategy.

Syntax

EXPLAIN statement;
EXPLAIN QUERY PLAN statement;
ParameterDescription
statementAny SQL statement (SELECT, INSERT, UPDATE, DELETE, etc.).

EXPLAIN

The EXPLAIN prefix causes Turso to return the sequence of virtual machine (VDBE) opcodes that would be used to execute the statement, rather than executing it.
EXPLAIN SELECT * FROM users WHERE id = 1;
-- addr | opcode     | p1 | p2 | p3 | p4       | p5
-- 0    | Init       | 0  | 9  | 0  |          | 0
-- 1    | OpenRead   | 0  | 2  | 0  | 3        | 0
-- 2    | SeekRowid  | 0  | 8  | 1  |          | 0
-- ...

Output columns

ColumnDescription
addrInstruction address (sequential integer).
opcodeThe operation name (e.g., OpenRead, SeekRowid, Column, ResultRow).
p1First operand.
p2Second operand.
p3Third operand.
p4Fourth operand (often a string value such as table name or collation).
p5Fifth operand (flags).
The VDBE bytecode is the same format as SQLite’s. Turso’s bytecode output is useful for deep compatibility comparisons or debugging the query compiler.

EXPLAIN QUERY PLAN

Provides a high-level description of the strategy the query optimizer chose for executing a statement. This form is more useful than raw EXPLAIN for understanding query performance.
EXPLAIN QUERY PLAN SELECT * FROM users WHERE name = 'Alice';
-- id | parent | notused | detail
-- 2  | 0      | 0       | SCAN users
CREATE INDEX idx_name ON users(name);
EXPLAIN QUERY PLAN SELECT * FROM users WHERE name = 'Alice';
-- id | parent | notused | detail
-- 3  | 0      | 0       | SEARCH users USING INDEX idx_name (name=?)

Output columns

ColumnDescription
idA unique identifier for this step.
parentThe id of the parent step (0 for top-level).
notusedReserved for future use (always 0).
detailHuman-readable description of the execution step.

Common detail messages

Detail patternMeaning
SCAN tableFull table scan (no index used).
SEARCH table USING INDEX idx (col=?)Index lookup on the specified column.
SEARCH table USING INTEGER PRIMARY KEY (rowid=?)Direct rowid lookup.
USE TEMP B-TREE FOR ORDER BYA temporary B-tree is used for sorting.
USE TEMP B-TREE FOR DISTINCTA temporary B-tree is used for deduplication.
COMPOUND SUBQUERYIndicates a UNION, INTERSECT, or EXCEPT.
CORRELATED SCALAR SUBQUERYA correlated subquery that returns a single value.
LIST SUBQUERYA subquery used with IN.

Examples

Comparing query plans

CREATE TABLE orders (
    id INTEGER PRIMARY KEY,
    customer_id INTEGER,
    total REAL
);

-- Without index: full table scan
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
-- SCAN orders

-- After creating an index
CREATE INDEX idx_customer ON orders(customer_id);
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
-- SEARCH orders USING INDEX idx_customer (customer_id=?)

Join order

EXPLAIN QUERY PLAN
SELECT o.id, c.name
FROM orders o
INNER JOIN customers c ON c.id = o.customer_id
WHERE c.name = 'Alice';
-- SCAN orders AS o
-- SEARCH customers AS c USING INTEGER PRIMARY KEY (rowid=?)

Subqueries

EXPLAIN QUERY PLAN
SELECT * FROM orders
WHERE customer_id IN (SELECT id FROM customers WHERE active = 1);
-- SCAN orders
-- LIST SUBQUERY
--   SCAN customers

Reading EXPLAIN bytecode

EXPLAIN SELECT name FROM employees WHERE id = 5;
Key opcodes you will see in output:
OpcodeMeaning
InitEntry point; jumps to the main program.
OpenReadOpens a cursor on a table or index for reading.
SeekRowidPositions the cursor on a row by rowid.
ColumnReads a column value from the current cursor position.
ResultRowEmits a result row to the caller.
HaltEnds program execution.
NextAdvances the cursor to the next row.
FilterEvaluates a filter condition (used in modern SQLite bytecode).
Use EXPLAIN QUERY PLAN when tuning query performance. Use EXPLAIN only when you need to inspect the exact bytecode, such as when comparing Turso’s output against SQLite for compatibility testing.

See also

  • CREATE INDEX — create indexes to speed up queries
  • SELECT — the statement most commonly analyzed with EXPLAIN

Build docs developers (and LLMs) love