From bff51d480bac2a36f6e2edfbfe772261a7c290b1 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sat, 18 Jan 2025 10:54:44 -0500 Subject: [PATCH v31 4/4] DEBUG: Add skip scan disable GUCs. --- src/include/access/nbtree.h | 5 +++ src/backend/access/nbtree/nbtpreprocesskeys.c | 37 +++++++++++++++++++ src/backend/access/nbtree/nbtutils.c | 3 ++ src/backend/utils/misc/guc_tables.c | 34 +++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index c8708f2fd..dea7f87c0 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1177,6 +1177,11 @@ typedef struct BTOptions #define PROGRESS_BTREE_PHASE_PERFORMSORT_2 4 #define PROGRESS_BTREE_PHASE_LEAF_LOAD 5 +/* GUC parameters (just a temporary convenience for reviewers) */ +extern PGDLLIMPORT int skipscan_prefix_cols; +extern PGDLLIMPORT bool skipscan_skipsupport_enabled; +extern PGDLLIMPORT bool skipscan_iprefix_enabled; + /* * external entry points for btree, in nbtree.c */ diff --git a/src/backend/access/nbtree/nbtpreprocesskeys.c b/src/backend/access/nbtree/nbtpreprocesskeys.c index 7b2b0c44e..58f639ed2 100644 --- a/src/backend/access/nbtree/nbtpreprocesskeys.c +++ b/src/backend/access/nbtree/nbtpreprocesskeys.c @@ -21,6 +21,33 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" +/* + * GUC parameters (temporary convenience for reviewers). + * + * To disable all skipping, set skipscan_prefix_cols=0. Otherwise set it to + * the attribute number that you wish to make the last attribute number that + * we can add a skip scan key for. For example, skipscan_prefix_cols=1 makes + * an index scan with qual "WHERE b = 1 AND d = 42" generate a skip scan key + * on the column 'a' (which is attnum 1) only, preventing us from adding one + * for the column 'c'. And so only the scan key on 'b' (not the one on 'd') + * gets marked required within _bt_preprocess_keys -- there is no 'c' skip + * array to "anchor the required-ness" of 'b' through 'c' into 'd'. + */ +int skipscan_prefix_cols = INDEX_MAX_KEYS; + +/* + * skipscan_skipsupport_enabled can be used to avoid using skip support. Used + * to quantify the performance benefit that comes from having dedicated skip + * support, with a given opclass and test query. + */ +bool skipscan_skipsupport_enabled = true; + +/* + * skipscan_iprefix_enabled can be used to disable optimizations used when the + * maintenance overhead of skip arrays stops paying for itself + */ +bool skipscan_iprefix_enabled = true; + typedef struct BTScanKeyPreproc { ScanKey inkey; @@ -1643,6 +1670,10 @@ _bt_preprocess_array_keys(IndexScanDesc scan, int *new_numberOfKeys) so->arrayKeys[numArrayKeys].low_compare = NULL; /* for now */ so->arrayKeys[numArrayKeys].high_compare = NULL; /* for now */ + /* Temporary testing GUC can disable the use of skip support */ + if (!skipscan_skipsupport_enabled) + so->arrayKeys[numArrayKeys].sksup = NULL; + /* * We'll need a 3-way ORDER proc. Set that up now. */ @@ -2146,6 +2177,12 @@ _bt_num_array_keys(IndexScanDesc scan, Oid *skip_eq_ops, int *numSkipArrayKeys) if (attno_has_rowcompare) break; + /* + * Apply temporary testing GUC that can be used to disable skipping + */ + if (attno_inkey > skipscan_prefix_cols) + break; + /* * Now consider next attno_inkey (or keep going if this is an * additional scan key against the same attribute) diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 2dddaba7a..3d26bea92 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2475,6 +2475,9 @@ _bt_set_startikey(IndexScanDesc scan, BTReadPageState *pstate) if (so->numberOfKeys == 0) return; + if (!skipscan_iprefix_enabled) + return; + /* minoff is an offset to the lowest non-pivot tuple on the page */ iid = PageGetItemId(pstate->page, pstate->minoff); firsttup = (IndexTuple) PageGetItem(pstate->page, iid); diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 989825d3a..4a37044cd 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -28,6 +28,7 @@ #include "access/commit_ts.h" #include "access/gin.h" +#include "access/nbtree.h" #include "access/slru.h" #include "access/toast_compression.h" #include "access/twophase.h" @@ -1788,6 +1789,28 @@ struct config_bool ConfigureNamesBool[] = }, #endif + /* XXX Remove before commit */ + { + {"skipscan_skipsupport_enabled", PGC_SUSET, DEVELOPER_OPTIONS, + NULL, NULL, + GUC_NOT_IN_SAMPLE + }, + &skipscan_skipsupport_enabled, + true, + NULL, NULL, NULL + }, + + /* XXX Remove before commit */ + { + {"skipscan_iprefix_enabled", PGC_SUSET, DEVELOPER_OPTIONS, + NULL, NULL, + GUC_NOT_IN_SAMPLE + }, + &skipscan_iprefix_enabled, + true, + NULL, NULL, NULL + }, + { {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS, gettext_noop("Shows whether datetimes are integer based."), @@ -3734,6 +3757,17 @@ struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + /* XXX Remove before commit */ + { + {"skipscan_prefix_cols", PGC_SUSET, DEVELOPER_OPTIONS, + NULL, NULL, + GUC_NOT_IN_SAMPLE + }, + &skipscan_prefix_cols, + INDEX_MAX_KEYS, 0, INDEX_MAX_KEYS, + NULL, NULL, NULL + }, + { /* Can't be set in postgresql.conf */ {"server_version_num", PGC_INTERNAL, PRESET_OPTIONS, -- 2.49.0