1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Reduce btree scan overhead for < and > strategies

For <, <=, > and >= strategies, mark the first scan key
as already matched if scanning in an appropriate direction.
If index tuple contains no nulls we can skip the first
re-check for each tuple.

Author: Rajeev Rastogi
Reviewer: Haribabu Kommi
Rework of the code and comments by Simon Riggs
This commit is contained in:
Simon Riggs
2014-11-18 10:24:55 +00:00
parent dedae6c211
commit 606c0123d6
3 changed files with 35 additions and 0 deletions

View File

@@ -996,6 +996,33 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (goback)
offnum = OffsetNumberPrev(offnum);
/*
* By here the scan position is now set for the first key. If all
* further tuples are expected to match we set the SK_BT_MATCHED flag
* to avoid re-checking the scan key later. This is a big win for
* slow key matches though is still significant even for fast datatypes.
*/
switch (startKeys[0]->sk_strategy)
{
case BTEqualStrategyNumber:
break;
case BTGreaterEqualStrategyNumber:
case BTGreaterStrategyNumber:
if (ScanDirectionIsForward(dir))
startKeys[0]->sk_flags |= SK_BT_MATCHED;
break;
case BTLessEqualStrategyNumber:
case BTLessStrategyNumber:
if (ScanDirectionIsBackward(dir))
startKeys[0]->sk_flags |= SK_BT_MATCHED;
break;
default:
break;
}
/*
* Now load data from the first page of the scan.
*/

View File

@@ -1429,6 +1429,13 @@ _bt_checkkeys(IndexScanDesc scan,
bool isNull;
Datum test;
/*
* If the scan key has already matched we can skip this key, as
* long as the index tuple does not contain NULL values.
*/
if (key->sk_flags & SK_BT_MATCHED && !IndexTupleHasNulls(tuple))
continue;
/* row-comparison keys need special processing */
if (key->sk_flags & SK_ROW_HEADER)
{