Skip to content

perf: migrate to unnest (from VALUES) for CTEs, INSERT .. SELECT FROM, SELECT/UPDATE FROM - #2003

Merged
jkaczman merged 5 commits into
mainfrom
jk-subqueries-repl-values-w-unnest
Nov 10, 2026
Merged

jkaczman merged 5 commits into
mainfrom
jk-subqueries-repl-values-w-unnest

Conversation

@jkaczman

@jkaczman jkaczman commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Works off the previous changes implementing splitting INSERT with unnest (#1988, #2000) to now implement this unnest functionality to be used when re-writing subqueries (as opposed to re-writing the SQL to have an explicit VALUES clause with all the DataRows inlined) when we send the subquery data rows back to Postgres in the outer statement to be evaluated.

This should be a considerable speedup vs. before; if we had 10,000 DataRows returned, it's much cheaper to include the data in an array in a Bind parameter vs. creating a new SQL statement with 10,000 tuples and deparsing it.

Not handled for WHERE clause yet. Will follow up.

@jkaczman
jkaczman added this pull request to stack #1986 November 9, 2026 21:21
@jkaczman
jkaczman force-pushed the jk-subqueries-repl-values-w-unnest branch from b31ce78 to 3b31f94 Compare November 9, 2026 21:34
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Metal bench (arm64) failed. 1 of 475 measures outside bounds.

suite throughput cpu/txn user cycles/txn user instr/txn kernel cycles/txn kernel instr/txn ctx/txn
pooler 18.73 (+0.7% ± 1.0%) 18,041 (+1.2% ± 0.2%) 32,046 (+0.1% ± 0.04%) 29,633 (+0.1% ± 1.8%) 51,184 (-0.2% ± 0.3%)
lb 19.34 (+1.1% ± 0.7%) 18,649 (+1.2% ± 0.5%) 32,939 (+0.0% ± 0.08%) 30,403 (+0.6% ± 1.0%) 52,351 (-0.1% ± 0.2%)
sharding-w2 33.98 (+1.4% ± 1.5%) 46,270 (+1.1% ± 2.7%) 97,433 (+0.0% ± 0.01%) 42,071 (+0.8% ± 4.1%) 53,681 (+0.0% ± 0.2%) 1.543 (+0.1% ± 0.1%)
sharding-w8 241,163 (+0.4% ± 0.6%) 29.81 (-0.5% ± 1.1%) 45,352 (-1.7% ± 2.8%) 52,975 (+0.0% ± 0.2%) 37,032 (+1.0% ± 2.9%) 42,364 (+0.0% ± 0.3%) 0.1654 (+1.7% ± 5.0%)
Counters per txn
suite frontend stall l1i refill backend stall
pooler 7,114 (-0.5% ± 0.9%) 2,563 (-0.1% ± 0.2%)
lb 7,433 (-0.0% ± 1.2%) 2,626 (+0.2% ± 0.5%)
sharding-w2 20,000 (+1.5% ± 8.1%) 4,310 (+0.2% ± 5.6%)
sharding-w8 20,835 (-6.1% ± 6.6%) 4,157 (-4.6% ± 3.8%)
benchmark measure result baseline change bound
full_named_cached::min_max_sum instructions 130,486 128,512 +1.54% ± 0.00% +1%

Microbench: 461 of 462 measures within bounds.

Hot code per txn
path base head change
pooler 109.1 KB 109.9 KB +0.8 KB
sharding-w2 164.4 KB 163.9 KB -0.6 KB

pooler:

crate base head change
pgdog::frontend::client::query_engine 19.7 KB 19.8 KB +0.1 KB
tokio 18.2 KB 18.6 KB +0.3 KB
pgdog::backend::pool 17.4 KB 17.2 KB -0.2 KB
aws-lc (TLS crypto) 10.2 KB 9.8 KB -0.4 KB
rustls (TLS) 8.2 KB 8.4 KB +0.1 KB
pgdog::frontend (other) 7.8 KB 7.8 KB +0.0 KB
pgdog::backend::server 7.1 KB 7.3 KB +0.2 KB
other 5.8 KB 6.2 KB +0.5 KB
everything else 14.7 KB 14.9 KB +0.2 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 5.4 KB +0.0 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 5.4 KB +0.0 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 4.1 KB +0.0 KB
tokio::runtime::task::raw::poll 3.2 KB +0.1 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 2.9 KB +0.0 KB

sharding-w2:

crate base head change
pgdog::frontend::router 28.5 KB 28.8 KB +0.2 KB
pgdog::frontend::client::query_engine 21.1 KB 21.4 KB +0.2 KB
tokio 19.0 KB 18.8 KB -0.2 KB
pgdog::backend::pool 17.9 KB 18.2 KB +0.2 KB
aws-lc (TLS crypto) 12.6 KB 12.2 KB -0.3 KB
other 9.8 KB 9.5 KB -0.2 KB
pgdog::frontend (other) 8.4 KB 8.6 KB +0.2 KB
rustls (TLS) 8.2 KB 8.1 KB -0.1 KB
everything else 38.9 KB 38.3 KB -0.6 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 6.0 KB +0.0 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 5.5 KB +0.2 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 4.1 KB +0.1 KB
tokio::runtime::task::raw::poll 3.4 KB +0.2 KB
pgdog::frontend::router::parser::query::select::<impl pgdog::frontend::router::parser::que 3.4 KB +0.0 KB
lb flamegraph vs 4bb1985

lb

Open interactive for hover, zoom and search.

lb removed

Open interactive.

microbench flamegraph vs 4bb1985

microbench

Open interactive for hover, zoom and search.

microbench removed

Open interactive.

pooler flamegraph vs 4bb1985

pooler

Open interactive for hover, zoom and search.

pooler removed

Open interactive.

sharding-w2 flamegraph vs 4bb1985

sharding-w2

Open interactive for hover, zoom and search.

sharding-w2 removed

Open interactive.

sharding-w8 flamegraph vs 4bb1985

sharding-w8

Open interactive for hover, zoom and search.

sharding-w8 removed

Open interactive.

Logs

lb, microbench, pooler, sharding-w2, sharding-w8, verdict.json

Compared b0a3b72 with 4bb1985 on m8g.metal-24xl (spot).

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Metal bench (x86) passed. All 475 measures within bounds.

suite throughput cpu/txn user cycles/txn user instr/txn kernel cycles/txn kernel instr/txn ctx/txn
pooler 34.88 (+0.3% ± 0.3%) 23,065 (+1.2% ± 0.9%) 33,900 (+0.0% ± 0.02%) 58,148 (+0.1% ± 0.4%) 38,508 (-0.0% ± 0.1%)
lb 35.78 (+0.1% ± 0.2%) 24,123 (+0.8% ± 0.5%) 34,852 (+0.0% ± 0.03%) 58,847 (-0.3% ± 0.3%) 39,198 (-0.1% ± 0.2%)
sharding-w2 56.4 (-0.1% ± 0.5%) 52,924 (-0.5% ± 1.2%) 101,308 (+0.0% ± 0.01%) 72,885 (+0.0% ± 1.7%) 43,110 (+0.0% ± 0.1%) 1.394 (+0.0% ± 0.4%)
sharding-w8 147,976 (-0.4% ± 0.8%) 48.25 (+0.0% ± 0.5%) 58,441 (+0.6% ± 1.1%) 56,800 (+0.1% ± 0.03%) 64,040 (-0.4% ± 0.2%) 34,225 (+0.0% ± 0.2%) 0.1682 (-1.2% ± 1.0%)
Counters per txn
suite frontend stall l1i refill backend stall
pooler 75,591 (+4.3% ± 1.0%) 3,626 (+2.1% ± 0.2%)
lb 78,319 (+3.9% ± 1.2%) 3,743 (+1.7% ± 0.06%)
sharding-w2 155,227 (-0.1% ± 2.3%) 5,936 (-0.7% ± 0.4%)
sharding-w8 123,404 (+1.5% ± 0.5%) 4,873 (+1.1% ± 0.4%)

Microbench: all 462 measures within bounds.

Microbench latency: 1 benches changed more than 3%
benchmark latency baseline change instructions change
full_extended_cached::delete_all_shards 19,460 ns 18,364 ns +5.97% ± 3.85% +0.06% ± 0.00%
Hot code per txn
path base head change
pooler 101.2 KB 105.4 KB +4.1 KB
sharding-w2 158.4 KB 158.7 KB +0.2 KB

pooler:

crate base head change
pgdog::frontend::client::query_engine 19.3 KB 20.4 KB +1.1 KB
tokio 17.6 KB 17.7 KB +0.1 KB
pgdog::backend::pool 16.2 KB 16.6 KB +0.4 KB
pgdog::frontend (other) 8.8 KB 9.1 KB +0.3 KB
rustls (TLS) 7.1 KB 7.4 KB +0.3 KB
aws-lc (TLS crypto) 7.1 KB 7.3 KB +0.2 KB
pgdog::backend::server 5.7 KB 7.0 KB +1.3 KB
other 5.6 KB 5.7 KB +0.1 KB
everything else 13.9 KB 14.2 KB +0.4 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 6.9 KB +0.2 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 5.9 KB +0.2 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 5.0 KB +0.7 KB
tokio::runtime::task::raw::poll 3.8 KB +0.2 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 3.1 KB +0.1 KB

sharding-w2:

crate base head change
pgdog::frontend::router 26.4 KB 27.3 KB +0.9 KB
pgdog::frontend::client::query_engine 21.8 KB 22.2 KB +0.4 KB
tokio 18.3 KB 18.1 KB -0.2 KB
pgdog::backend::pool 17.6 KB 17.1 KB -0.6 KB
other 10.0 KB 10.3 KB +0.3 KB
aws-lc (TLS crypto) 10.1 KB 10.2 KB +0.1 KB
pgdog::frontend (other) 10.0 KB 10.0 KB +0.0 KB
rustls (TLS) 7.5 KB 7.4 KB -0.1 KB
everything else 36.7 KB 36.1 KB -0.6 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 7.5 KB +0.0 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 6.1 KB +0.0 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 4.9 KB +0.2 KB
pgdog::frontend::router::parser::query::select::<impl pgdog::frontend::router::parser::que 4.1 KB +0.1 KB
tokio::runtime::task::raw::poll 3.9 KB +0.1 KB
lb flamegraph vs 4bb1985

lb

Open interactive for hover, zoom and search.

lb removed

Open interactive.

microbench flamegraph vs 4bb1985

microbench

Open interactive for hover, zoom and search.

microbench removed

Open interactive.

pooler flamegraph vs 4bb1985

pooler

Open interactive for hover, zoom and search.

pooler removed

Open interactive.

sharding-w2 flamegraph vs 4bb1985

sharding-w2

Open interactive for hover, zoom and search.

sharding-w2 removed

Open interactive.

sharding-w8 flamegraph vs 4bb1985

sharding-w8

Open interactive for hover, zoom and search.

sharding-w8 removed

Open interactive.

Logs

lb, microbench, pooler, sharding-w2, sharding-w8, verdict.json

Compared b0a3b72 with 4bb1985 on c7a.metal-48xl (spot).

@jkaczman
jkaczman force-pushed the jk-subqueries-repl-values-w-unnest branch 4 times, most recently from a7a706c to 422f97c Compare November 9, 2026 22:01
@codecov

codecov Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

@jkaczman
jkaczman force-pushed the jk-subqueries-repl-values-w-unnest branch 3 times, most recently from f3aac4a to dc61d2e Compare November 10, 2026 00:31
Base automatically changed from jk-unnest-select-targets to main November 10, 2026 02:12
@jkaczman
jkaczman force-pushed the jk-subqueries-repl-values-w-unnest branch from dc61d2e to 1524789 Compare November 10, 2026 02:12
@jkaczman
jkaczman marked this pull request as ready for review November 10, 2026 03:20
@jkaczman
jkaczman merged commit 81a9f08 into main Nov 10, 2026
46 of 47 checks passed
@jkaczman
jkaczman deleted the jk-subqueries-repl-values-w-unnest branch November 10, 2026 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant