⌘K ctrl+k
Search Shortcut cmd + k | ctrl + k
EXPLAIN ANALYZE: Profile Queries

Prepending a query with EXPLAIN ANALYZE both pretty-prints the query plan, and executes it, providing run-time performance numbers and the actual cardinality (number of rows produced) for every operator.

EXPLAIN ANALYZE SELECT * FROM tbl;

Note that the cumulative wall-clock time that is spent on every operator is shown. When multiple threads are processing the query in parallel, the total processing time of the query may be lower than the sum of all the times spent on the individual operators.

For multi-file reads (e.g., reading multiple Parquet files), the output includes the file names being read.

Below is an example of running EXPLAIN ANALYZE on a query:

CREATE TABLE students (name VARCHAR, sid INTEGER);
CREATE TABLE exams (eid INTEGER, subject VARCHAR, sid INTEGER);
INSERT INTO students VALUES ('Mark', 1), ('Joe', 2), ('Matthew', 3);
INSERT INTO exams VALUES (10, 'Physics', 1), (20, 'Chemistry', 2), (30, 'Literature', 3);

EXPLAIN ANALYZE
    SELECT name
    FROM students
    JOIN exams USING (sid)
    WHERE name LIKE 'Ma%';
╭─ Summary ───────────╮
│ Total Time: 0.0015s │
╰─────────────────────╯
╭─ Projection ────────────────────────────────────────────╮
│ Projections: name                                       │
│ 2 rows                                              0µs │
╰────────────────────────────┒┎───────────────────────────╯
╭─ Hash Join ────────────────┚┖───────────────────────────╮
│ Join Type: INNER                                        │
│ Conditions: sid = sid                                   │
│ 2 rows                                              0µs │
╰────────────────────────────┰┰───────────────────────────╯
                             ┃┠─────────────────────────────────────────────┰┒
╭─ Table Scan ───────────────┚┖───────────────────────────╮  ╭─ Table Scan ─┚┖─────────────╮
│ Table: memory.main.exams                                │  │ Table: memory.main.students │
│ Type: Sequential Scan                                   │  │ Type: Sequential Scan       │
│ Projections: sid                                        │  │ Projections: sid, name      │
│ Dynamic Filters:                                        │  │ Filters: name >= 'Ma'       │
│ optional: (sid IN (1, 3)) AND optional: sid IN PRF(sid) │  │ Row Groups Scanned: 1 / 1   │
│ Row Groups Scanned: 1 / 1                               │  │ 2 rows                  0µs │
│ 2 rows                                              0µs │  ╰─────────────────────────────╯
╰─────────────────────────────────────────────────────────╯

Each operator shows the number of rows it produced and the time spent in it. Scan operators also show the number of row groups scanned and any dynamic filters that were pushed into them at runtime, e.g., by the hash join.

See Also

For more information, see the ”Profiling” page.

© 2026 DuckDB Foundation, Amsterdam NL
DuckDB Home Code of Conduct Trademark Use Blog