aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtsearch.c27
-rw-r--r--src/backend/access/nbtree/nbtutils.c7
-rw-r--r--src/include/access/nbtree.h1
3 files changed, 35 insertions, 0 deletions
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 203b9691baa..6150b24d02f 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -997,6 +997,33 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
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.
*/
if (!_bt_readpage(scan, dir, offnum))
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index f8f8e69be7f..a5604679b4a 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -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)
{
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index c8bb3f5d668..6ecd2ced62d 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -618,6 +618,7 @@ typedef BTScanOpaqueData *BTScanOpaque;
*/
#define SK_BT_REQFWD 0x00010000 /* required to continue forward scan */
#define SK_BT_REQBKWD 0x00020000 /* required to continue backward scan */
+#define SK_BT_MATCHED 0x00040000 /* required to skip further key match */
#define SK_BT_INDOPTION_SHIFT 24 /* must clear the above bits */
#define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT)
#define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT)