Re: Adding skip scan (including MDAM style range skip scan) to nbtree
Alena Rybakina <a.rybakina@postgrespro.ru>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
nbtree: Always set skipScan flag on rescan.
- 454c046094ab 19 (unreleased) landed
- bee763aea13f 18.0 landed
-
meson: Build numeric.c with -ftree-vectorize.
- 9016fa7e3bcd 19 (unreleased) cited
-
Fix "variable not found in subplan target lists" in semijoin de-duplication.
- b8a1bdc458e3 19 (unreleased) cited
-
Revert "nbtree: Remove useless row compare arg."
- dd2ce3792754 18.0 landed
-
nbtree: Remove useless row compare arg.
- 54c6ea8c81db 18.0 cited
-
Prevent premature nbtree array advancement.
- 5f4d98d4f371 18.0 landed
-
nbtree: tighten up array recheck rules.
- 7e25c9363a82 18.0 landed
-
Avoid treating nonrequired nbtree keys as required.
- 0f08df406822 18.0 landed
-
Adjust overstrong nbtree skip array assertion.
- 9d924dbb3710 18.0 landed
-
Make NULL tuple values always advance skip arrays.
- b75fedcab791 18.0 cited
-
Avoid extra index searches through preprocessing.
- b3f1a13f22f9 18.0 landed
-
Improve nbtree skip scan primitive scan scheduling.
- 21a152b37f36 18.0 landed
-
Further optimize nbtree search scan key comparisons.
- 8a510275dd6b 18.0 landed
-
Add nbtree skip scan optimization.
- 92fe23d93aa3 18.0 landed
-
Improve nbtree array primitive scan scheduling.
- 9a2e2a285a14 18.0 landed
-
nbtree: Make BTMaxItemSize into object-like macro.
- 426ea611171d 18.0 landed
-
Show index search count in EXPLAIN ANALYZE, take 2.
- 0fbceae841cb 18.0 landed
-
Make parallel nbtree index scans use an LWLock.
- 67fc4c9fd7fa 18.0 landed
-
Show index search count in EXPLAIN ANALYZE.
- 5ead85fbc811 18.0 landed
-
Avoid nbtree parallel scan currPos confusion.
- b5ee4e52026b 18.0 cited
-
nbtree: Remove useless 'strat' local variable.
- b6558e4f837e 18.0 landed
-
Normalize nbtree truncated high key array behavior.
- 79fa7b3b1a44 18.0 landed
-
Refactor handling of nbtree array redundancies.
- b524974106ac 18.0 landed
-
Fix nbtree pgstats accounting with parallel scans.
- c00c54a9ac1e 18.0 landed
- fb4f5e58af97 17.0 landed
-
Avoid parallel nbtree index scan hangs with SAOPs.
- d8adfc18bebf 18.0 landed
- a24bffc021d9 17.0 landed
-
Show Parallel Bitmap Heap Scan worker stats in EXPLAIN ANALYZE
- 5a1e6df3b84c 18.0 cited
-
Enhance nbtree ScalarArrayOp execution.
- 5bf748b86bc6 17.0 cited
-
Skip checking of scan keys required for directional scan in B-tree
- e0b1ee17dc3a 17.0 cited
-
Instead of using a numberOfRequiredKeys count to distinguish required
- 7ccaf13a06b8 8.2.0 cited
Hi! On 26.03.2025 02:45, Peter Geoghegan wrote: > On Sat, Mar 22, 2025 at 1:47 PM Peter Geoghegan<pg@bowt.ie> wrote: >> Attached is v30, which fully replaces the pstate.prechecked >> optimization with the new _bt_skip_ikeyprefix optimization (which now >> appears in v30-0002-Lower-nbtree-skip-array-maintenance-overhead.patch, >> and not in 0003-*, due to my committing the primscan scheduling patch >> just now). > Attached is v31, which has a much-improved _bt_skip_ikeyprefix (which > I've once again renamed, this time to _bt_set_startikey). > I reviewed your first patch and noticed that you added the ability to define new quals if the first column isn't usedin the query. I replied an example like this: CREATE TABLE sales ( id SERIAL PRIMARY KEY, region TEXT, product TEXT, year INT ); INSERT INTO sales (region, product, year) SELECT CASE WHEN i % 4 <= 1 THEN 'North' WHEN i % 4 <= 2 THEN 'South' WHEN i % 4 <= 3 THEN 'East' ELSE 'West' END, CASE WHEN random() > 0.5 THEN 'Laptop' ELSE 'Phone' END, 2023 FROM generate_series(1, 100000) AS i; vacuum analyze; CREATE INDEX sales_idx ON sales (region, product, year); EXPLAIN ANALYZE SELECT * FROM sales WHERE product = 'Laptop' AND year = 2023; master gives the query plan with SeqScan: QUERY PLAN --------------------------------------------------------------------------------------------------------------- Seq Scan on sales (cost=0.00..2137.00 rows=49703 width=19) (actual time=0.035..31.438 rows=50212.00 loops=1) Filter: ((product = 'Laptop'::text) AND (year = 2023)) Rows Removed by Filter: 49788 Buffers: shared hit=637 Planning: Buffers: shared hit=35 Planning Time: 0.695 ms Execution Time: 33.942 ms (8 rows) Your patch sets fair costs for it and it helps take into account index scan path and in my opinion it is perfect!) QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on sales (cost=652.46..2031.86 rows=49493 width=19) (actual time=18.039..33.723 rows=49767.00 loops=1) Recheck Cond: ((product = 'Laptop'::text) AND (year = 2023)) Heap Blocks: exact=637 Buffers: shared hit=642 read=50 -> Bitmap Index Scan on sales_idx (cost=0.00..640.09 rows=49493 width=0) (actual time=17.756..17.756 rows=49767.00 loops=1) Index Cond: ((product = 'Laptop'::text) AND (year = 2023)) Index Searches: 4 Buffers: shared hit=5 read=50 Planning: Buffers: shared hit=55 read=1 Planning Time: 0.984 ms Execution Time: 36.940 ms I think it would be useful to show information that we used an index scan but at the same time we skipped the "region" column and I assume we should output how many distinct values the "region" column had. For example it will look like this "*Skip Scan on region (4 distinct values)"*: QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on sales (cost=652.46..2031.86 rows=49493 width=19) (actual time=18.039..33.723 rows=49767.00 loops=1) Recheck Cond: ((product = 'Laptop'::text) AND (year = 2023)) Heap Blocks: exact=637 Buffers: shared hit=642 read=50 -> Bitmap Index Scan on sales_idx (cost=0.00..640.09 rows=49493 width=0) (actual time=17.756..17.756 rows=49767.00 loops=1) Index Cond: ((product = 'Laptop'::text) AND (year = 2023)) *Skip Scan on region (4 distinct values)* Index Searches: 4 Buffers: shared hit=5 read=50 Planning: Buffers: shared hit=55 read=1 Planning Time: 0.984 ms Execution Time: 36.940 ms What do you think? I didn't see any regression tests. Maybe we should add some tests? To be honest I didn't see it mentioned in the commit message but I might have missed something. -- Regards, Alena Rybakina Postgres Professional