mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Normalize nbtree truncated high key array behavior.
Commit5bf748b8
taught nbtree ScalarArrayOp index scans to decide when and how to start the next primitive index scan based on physical index characteristics. This included rules for deciding whether to start a new primitive index scan (or whether to move onto the right sibling leaf page instead) that specifically consider truncated lower-order columns (-inf columns) from leaf page high keys. These omitted columns were treated as satisfying the scan's required scan keys, though only for scan keys marked required in the current scan direction (forward). Scan keys that didn't get this behavior (those marked required in the backwards direction only) usually didn't give the scan reasonable cause to reposition itself to a later leaf page (via another descent of the index in _bt_first), but _bt_advance_array_keys would nevertheless always give up by forcing another call to _bt_first. _bt_advance_array_keys was unwilling to allow the scan to continue onto the next leaf page, to reconsider whether we really should start another primitive scan based on the details of the sibling page's tuples. This didn't match its behavior with similar cases involving keys required in the current scan direction (forward), which seems unprincipled. It led to an excessive number of primitive scans/index descents for queries with a higher-order = array scan key (with dense, contiguous values) mixed with a lower-order required > or >= scan key. Bring > and >= strategy scan keys in line with other required scan key types: treat truncated -inf scan keys as having satisfied scan keys required in either scan direction (forwards and backwards alike) during array advancement. That way affected scans can continue to the right sibling leaf page. Advancement must now schedule an explicit recheck of the right sibling page's high key in cases involving > or >= scan keys. The recheck gives the scan a way to back out and start another primitive index scan (we can't just rely on _bt_checkkeys with > or >= scan keys). This work can be considered a stand alone optimization on top of the work from commit5bf748b8
. But it was written in preparation for an upcoming patch that will add skip scan to nbtree. In practice scans that use "skip arrays" will tend to be much more sensitive to any implementation deficiencies in this area. Author: Peter Geoghegan <pg@bowt.ie> Reviewed-By: Tomas Vondra <tomas@vondra.me> Discussion: https://postgr.es/m/CAH2-Wz=9A_UtM7HzUThSkQ+BcrQsQZuNhWOvQWK06PRkEp=SKQ@mail.gmail.com
This commit is contained in:
@ -1048,6 +1048,7 @@ typedef struct BTScanOpaqueData
|
||||
int numArrayKeys; /* number of equality-type array keys */
|
||||
bool needPrimScan; /* New prim scan to continue in current dir? */
|
||||
bool scanBehind; /* Last array advancement matched -inf attr? */
|
||||
bool oppositeDirCheck; /* explicit scanBehind recheck needed? */
|
||||
BTArrayKeyInfo *arrayKeys; /* info about each equality-type array key */
|
||||
FmgrInfo *orderProcs; /* ORDER procs for required equality keys */
|
||||
MemoryContext arrayContext; /* scan-lifespan context for array data */
|
||||
@ -1289,6 +1290,8 @@ extern void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir);
|
||||
extern void _bt_preprocess_keys(IndexScanDesc scan);
|
||||
extern bool _bt_checkkeys(IndexScanDesc scan, BTReadPageState *pstate, bool arrayKeys,
|
||||
IndexTuple tuple, int tupnatts);
|
||||
extern bool _bt_oppodir_checkkeys(IndexScanDesc scan, ScanDirection dir,
|
||||
IndexTuple finaltup);
|
||||
extern void _bt_killitems(IndexScanDesc scan);
|
||||
extern BTCycleId _bt_vacuum_cycleid(Relation rel);
|
||||
extern BTCycleId _bt_start_vacuum(Relation rel);
|
||||
|
Reference in New Issue
Block a user