Re: Adding skip scan (including MDAM style range skip scan) to nbtree
Peter Geoghegan <pg@bowt.ie>
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
Attachments
- v6-0001-Show-index-search-count-in-EXPLAIN-ANALYZE.patch (application/octet-stream) patch v6-0001
- v6-0003-Refactor-handling-of-nbtree-array-redundancies.patch (application/octet-stream) patch v6-0003
- v6-0002-Normalize-nbtree-truncated-high-key-array-behavio.patch (application/octet-stream) patch v6-0002
- v6-0004-Add-skip-scan-to-nbtree.patch (application/octet-stream) patch v6-0004
On Mon, Jul 15, 2024 at 2:34 PM Peter Geoghegan <pg@bowt.ie> wrote: > On Fri, Jul 12, 2024 at 1:19 AM <Masahiro.Ikeda@nttdata.com> wrote: > > I found the cost is estimated to much higher if the number of skipped attributes > > is more than two. Is it expected behavior? > > Yes and no. > > Honestly, the current costing is just placeholder code. It is totally > inadequate. I'm not surprised that you found problems with it. I just > didn't put much work into it, because I didn't really know what to do. Attached is v6, which finally does something sensible in btcostestimate. v6 is also the first version that supports parallel index scans that can skip. This works by extending the approach taken by scans with regular SAOP arrays to work with skip arrays. We need to serialize and deserialize the current array keys in shared memory, as datums -- we cannot just use simple BTArrayKeyInfo.cur_elem offsets with skip arrays. v6 also includes the patch that shows "Index Searches" in EXPLAIN ANALYZE output, just because it's convenient when testing the patch. This has been independently submitted as https://commitfest.postgresql.org/49/5183/, so probably doesn't need review here. v6 is the first version of the patch that is basically feature complete. I only have one big open item left: I must still fix certain regressions seen with queries that are very unfavorable for skip scan, where the CPU cost (but not I/O cost) of maintaining skip arrays slows things down. Overall, I'm making fast progress here. Back to the topic of the btcostestimate/planner changes. The rest of the email is a discussion of the cost model. The planner changes probably still have some problems, but all of the obvious problems have been fixed by v6. I found it useful to focus on making the cost model not have any obvious problems instead of trying to make it match a purely theoretical ideal. For example, your (Ikeda-san's) complaint about the "Index Scan using idx_id1_id2_id3 on public.test" test case having too high a cost (higher than the cost of a slower sequential scan) has been fixed. It's now about 3x cheaper than the sequential scan, since we're actually paying attention to ndistinct in v6. Just like when we cost SAOP arrays on HEAD, skip arrays are costed by pessimistically multiplying together the estimated number of array elements for all the scan's arrays, without trying to account for correlation between index columns. Being pessimistic about correlations like this is often wrong, but that still seems like the best bias we could have, all things considered. Plus it's nothing new. Range style skip arrays require a slightly more complicated approach to estimating the number of array elements: costing applies a selectivity estimate, taken from the associated index column's inequality keys, and applies that estimate to ndistinct itself. That way the cost of a range skip array is lower than an otherwise-equivalent simple skip array case (we prorate ndistinct with skip arrays). More importantly, the cost of more selectivity ranges is lower than the cost of less selective ranges. There is also a bias here: we don't account for skew in ndistinct. That's probably OK, because at least it's a bias *against* skip scan. The new cost model does not specifically try to account for how scans will behave when no skipping should be expected at all -- cases where a so-called "skip scan" degenerates into a full index scan. In theory, we should be costing these scans the same as before, since there has been no change in runtime behavior. Overall, the cost of full index scans with very many distinct prefix column values goes down by quite a bit -- the cost is something like 1/3 lower in typical cases. The problem with preserving the cost model from HEAD for these unfavorable cases for skip scan is that I don't feel that I understand the existing behavior. In practice the revised costing seems to be a somewhat more accurate predictor of the actual runtime of queries. Another problem is that I can't see a good way to make the behavior continuous when ndistinct starts small and grows so large that we should expect a true full index scan. (As I mentioned at the start of this email, there are unfixed regressions for these unfavorable cases, so I'm basing this analysis on the "set skipscan_prefix_cols = 0" behavior rather than the current default patch behavior to correct for that. This behavior matches HEAD with a full index scan, and should match the default behavior in a future version of the skip scan patch.) -- Peter Geoghegan