Hi, I decided to implement the idea from my previous message as a small heap-only experiment.
The attached patch lets heap_getnextslot() reuse the visible tuple offsets
already collected by page mode after the first tuple on a page. It preserves
the existing table AM and tuple-at-a-time executor interfaces. Scans without
page mode or with scan keys continue to use the existing path.
I benchmarked the patch against master. Negative values mean lower execution
time with the patch. Each cell shows the result for 5M and 10M rows,
respectively.
My patch relative to master:
all-visible
not-all-visible
5M / 10M
5M / 10M
count(*) (no qual) -6.6% / -8.6% -7.0% / -8.6%
count(*) WHERE pass-all -4.6% / -5.7% -8.6% / -9.2%
count(*) WHERE pass-none -11.0% / -10.3% -12.9% / -10.5%
I also repeated the benchmark with Amit's current v8 0001-0003 patch set, using
my patch as the baseline. Here negative values mean lower execution time with
Amit's patches.
Amit v8 relative to my patch:
all-visible
not-all-visible
5M / 10M 5M
/ 10M
count(*) (no qual) -4.1% / +0.6% -1.3% / +0.2%
count(*) WHERE pass-all -3.0% / -2.0% -2.3% / -1.0%
count(*) WHERE pass-none +0.1% / +1.5% +1.4% / +0.5%
These were release builds with -O2 on an Apple M5 Pro. The tables were
prewarmed and fit in shared_buffers. Parallel query, JIT, synchronized
sequential scans, and autovacuum were disabled.
For each query I used three warmup executions followed by 31 measured
executions. Each value above is calculated from two independent medians using
ABBA ordering. For the not-all-visible case, the visibility map was truncated
while the tuples themselves remained frozen.
The patch builds successfully and passes make check. I am posting it as a WIP
patch for discussion.
Best regards,
Denis Smirnov
v1-0001-Avoid-repeated-heapgettup_pagemode-calls-within-a.patch
Description: Binary data
