Control / engine · All operations
Plan and run queries
Query planning, optimisation, memory, caching, partitioning, parallelism.
Status
- In arcform
A feature, not a step
It lives in how a Protocol runs. Cargo.toml in arcform at fc62d6f
- Shape of the result
- not a data operation
- Level
- not a step
Variants
- Cache an intermediate result
Hold a table or column in memory, or in a stored copy, so later steps read it without recomputing it.
- Repartition the data
Split or redistribute rows over a set number of partitions or threads so the work runs in parallel.
Run within memory
Keep execution inside a memory limit by streaming batches and spilling to disk, and report memory and temporary-file use.
Parse and optimise the query plan
Turn a query into a plan and rewrite it, pushing filters, projections and limits toward the scan and reordering joins.
Reload from the source
Read a sheet again from its source, on demand, on a timer or when the file changes, clearing any cache first.
Maintain the database file
Checkpoint, vacuum and report on the size and storage of the database file and its connections.
What other tools call it
Meridian's classification; an independent blind rating agreed on 86.2% of 312 rows (exact class, version 2).
Apache DataFusion (21)
Constant foldingread 2026-09-27Evaluate constant expressions at plan time
DataFrame APIread 2026-09-27Build the same query plans through method calls instead of SQL text
Join Reorderingread 2026-09-27Reorder joins in the plan
Limit Pushdownread 2026-09-27Push LIMIT down the plan toward the scan
Memory limits enforcedread 2026-09-27Keep execution inside a configured memory limit
Parallel query executionread 2026-09-27Run a query plan across partitions in parallel
Parquet: Predicate push down (late materialization)read 2026-09-27Apply filters while decoding Parquet; stated as not on by default
Skip Parquet row groups and pages whose statistics cannot match the filter
Parquet: Row Group pruning on Bloom Filtersread 2026-09-27Skip Parquet row groups whose Bloom filter excludes the filter value
Predicate push downread 2026-09-27Push filters down the plan toward the scan
Projection push downread 2026-09-27Read only the columns the query needs
Query Optimizerread 2026-09-27Rewrite the logical plan with rule-based optimisations
SQL Parserread 2026-09-27Parse SQL text into a syntax tree
SQL Query Plannerread 2026-09-27Turn parsed SQL into a logical and physical query plan
Spilling (to disk) Groupingread 2026-09-27Aggregate data larger than memory by spilling to disk
Spilling (to disk) Sortread 2026-09-27Sort data larger than memory by spilling to disk
Spilling (to disk) Sort Merge Joinread 2026-09-27Sort-merge join data larger than memory by spilling to disk
Streaming Executionread 2026-09-27Execute plans as streams of record batches rather than whole tables
Streaming Groupingread 2026-09-27Aggregate over ordered input without buffering every group
Streaming Window Evaluationread 2026-09-27Evaluate window functions incrementally over a stream
repartitionread 2026-09-27DataFrame method: Repartition by a logical partitioning scheme
AWS Glue (3)
Autobalance Processingread 2026-09-27Redistribute the data among workers by Spark repartition
coalesceread 2026-09-27Reduce the frame to a given number of partitions; not a null-coalescing function
repartitionread 2026-09-27Redistribute the frame over a given number of partitions
DuckDB (17)
ANALYZEread 2026-09-27Recompute table statistics for the optimiser
CHECKPOINTread 2026-09-27Write the write-ahead log into the database file
VACUUMread 2026-09-27Reclaim space; a no-op kept for compatibility
check_peg_parserread 2026-09-27check_peg_parser table function
checkpointread 2026-09-27checkpoint table function
disable_peg_parserread 2026-09-27disable_peg_parser table function
duckdb_approx_database_countread 2026-09-27duckdb_approx_database_count table function
duckdb_connection_countread 2026-09-27duckdb_connection_count table function
duckdb_external_file_cacheread 2026-09-27duckdb_external_file_cache table function
duckdb_memoryread 2026-09-27duckdb_memory table function
duckdb_temporary_filesread 2026-09-27duckdb_temporary_files table function
enable_peg_parserread 2026-09-27enable_peg_parser table function
force_checkpointread 2026-09-27force_checkpoint table function
pragma_database_sizeread 2026-09-27pragma_database_size table function
pragma_metadata_inforead 2026-09-27pragma_metadata_info table function
pragma_storage_inforead 2026-09-27pragma_storage_info table function
sql_auto_completeread 2026-09-27sql_auto_complete table function
KNIME Analytics Platform (1)
Cacheread 2026-09-27Materialise the input table so downstream nodes read a stored copy
Power Query M (1)
Table.Bufferread 2026-09-27Load the table into memory once so later steps see a stable copy
subtoken (1)
subtoken_cache_clearread 2026-09-27Drop the cached vectors and return how many were dropped
Talend (10)
tBufferInputread 2026-09-27Read rows that tBufferOutput buffered, for processing in another subJob
tBufferOutputread 2026-09-27Collect rows in a buffer for later access, for example when the Job is exposed as a web service
tCacheClearread 2026-09-27Remove from memory a Spark RDD that tCacheOut persisted
tCacheInread 2026-09-27Read the Spark RDDs that tCacheOut persisted
tCacheOutread 2026-09-27Persist the input Spark RDDs at a chosen storage level for later use in the same Job
tHashInputread 2026-09-27Read the rows that tHashOutput loaded into cache memory
tHashOutputread 2026-09-27Load rows into cache memory for fast access later in the Job
tManagePartitionsread 2026-09-27Split the input dataset into a given number of partitions
tPartition (deprecated)read 2026-09-27Define how the input dataset is partitioned; superseded by tManagePartitions
tPartitionerread 2026-09-27Split the input rows into a given number of threads for parallel execution
VisiData (9)
cache-colread 2026-09-23Add or reset the value cache of current column
cache-colsread 2026-09-23Add or reset the value cache of all visible columns
reload-everyread 2026-09-23Reload the sheet every N seconds
reload-modifiedread 2026-09-23Reload the sheet when its source file changes
reload-rowsread 2026-09-23Reload rows while keeping the current columns
reload-selectedread 2026-09-23Reload the selected sheets from their sources
reload-sheetread 2026-09-23Reload current sheet from its source
s3-refresh-sheetread 2026-09-23Clear the s3fs cache for this path and reload
s3-refresh-sheet-allread 2026-09-23Clear the entire s3fs cache and reload
Background
A query optimiser tries to find the most efficient way to execute a query by considering the possible query plans, the sequences of steps that access the data.[1][2] Because SQL is declarative, there are typically many alternative ways to execute a given query, with widely varying performance.[2] In DuckDB, the EXPLAIN statement displays the physical plan, a tree of operators executed in a specific order to produce the result of the query.[3]
When to use it
DuckDB aims to perform well out of the box, so most workloads do not require any tuning.[4] DuckDB has no single configuration that is optimal for every workload, since the right settings depend on the workload's data, hardware and environment.[4] Reach for the engine's own controls when a query is slow, runs out of memory or needs explaining, and read its plan before changing any setting. (Meridian's view)
In DuckDB, EXPLAIN does not run the query, so the number of rows it shows for each operator is an estimate calculated from the statistics of the base tables.[3] In DuckDB, EXPLAIN ANALYZE runs and profiles the query, showing the central processing unit (CPU) time that each step takes.[4] Query optimisers cost each plan from estimates of its cardinality, the number of rows flowing through each step of the plan.[1] Poor cardinality estimates and uncaught correlation between query conditions are one of the main reasons why query optimisers pick poor query plans.[1] In DuckDB, the ANALYZE statement recomputes table statistics, which are used only for choosing the order in which tables are joined, and is recommended after large inserts or deletes.[5]
DuckDB can process datasets larger than the available memory by spilling to disk, into a temporary directory that the temp_directory option can change.[4] In DuckDB, blocking operators such as GROUP BY, JOIN, ORDER BY and window functions cannot output a single row until they have seen the last row of their input.[4] DuckDB may still run out of memory when several blocking operators appear in the same query, or with aggregate functions such as string_agg() that do not support offloading to disk.[4] In DuckDB, setting preserve_insertion_order to false lets results without an ORDER BY clause be reordered, which can reduce memory use when importing or exporting data larger than memory.[4] Look at the plan before raising a memory setting: reading fewer rows or joining in a better order attacks the cause rather than the symptom. (Meridian's view)
The method
Most query optimisers represent a plan as a tree of plan nodes, each a single operation, with intermediate results flowing from the leaves, which scan the data, up to the top.[1] Query optimisation is of two types: logical optimisation, which works out the sequence of operations that solves the query, and physical optimisation, which decides how each operation is carried out.[1] Cost-based query optimisers assign an estimated cost to each possible plan, from factors such as the input and output operations and CPU path length it needs, and choose the plan with the smallest cost.[1] Finding the exact optimal query plan is typically too costly, so query optimisation tries to approximate it with a good enough plan found in a reasonable time.[1] The order in which tables are joined largely determines a plan's performance, and most optimisers choose it with a dynamic programming algorithm pioneered by IBM's System R database project.[1]
In DuckDB, a table scan that does not apply, or push down, a filter condition used later in the plan performs unnecessary input and output.[4] DuckDB parallelises work by row groups, groups of rows stored together, so a query on k threads needs to scan at least k times 122,880 rows, the default row group size.[4] In DuckDB, a prepared statement completes parsing and planning once and caches their output, so repeated executions with different parameters skip those steps.[4]
Sources
- [1]Query optimization - Wikipediasecondary source
- [2]Query plan - Wikipediasecondary source
- [3]EXPLAIN: Inspect Query Plans – DuckDBdocumentation
- [4]Tuning Workloads – DuckDBdocumentation
- [5]ANALYZE Statement – DuckDBdocumentation