diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/sort/tuplesortvariants.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/utils/sort/tuplesortvariants.c b/src/backend/utils/sort/tuplesortvariants.c index 2933020dcc8..7ad4429ad3d 100644 --- a/src/backend/utils/sort/tuplesortvariants.c +++ b/src/backend/utils/sort/tuplesortvariants.c @@ -1387,14 +1387,17 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b, { Bucket bucket1; Bucket bucket2; + uint32 hash1; + uint32 hash2; IndexTuple tuple1; IndexTuple tuple2; TuplesortPublic *base = TuplesortstateGetPublic(state); TuplesortIndexHashArg *arg = (TuplesortIndexHashArg *) base->arg; /* - * Fetch hash keys and mask off bits we don't want to sort by. We know - * that the first column of the index tuple is the hash key. + * Fetch hash keys and mask off bits we don't want to sort by, so that the + * initial sort is just on the bucket number. We know that the first + * column of the index tuple is the hash key. */ Assert(!a->isnull1); bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1), @@ -1410,6 +1413,18 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b, return -1; /* + * If bucket values are equal, sort by hash values. This allows us to + * insert directly onto bucket/overflow pages, where the index tuples are + * stored in hash order to allow fast binary search within each page. + */ + hash1 = DatumGetUInt32(a->datum1); + hash2 = DatumGetUInt32(b->datum1); + if (hash1 > hash2) + return 1; + else if (hash1 < hash2) + return -1; + + /* * If hash values are equal, we sort on ItemPointer. This does not affect * validity of the finished index, but it may be useful to have index * scans in physical order. |