Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 25b1daf

Browse files
committed
Further optimize multi-key GIN searches.
If we're skipping past a certain TID, avoid decoding posting list segments that only contain smaller TIDs. Extracted from Alexander Korotkov's fast scan patch, heavily modified.
1 parent e20c70c commit 25b1daf

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

src/backend/access/gin/gindatapage.c

+34-4
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,49 @@ static void dataPlaceToPageLeafSplit(Buffer buf,
9696
XLogRecData **prdata, Page lpage, Page rpage);
9797

9898
/*
99-
* Read all TIDs from leaf data page to single uncompressed array.
99+
* Read TIDs from leaf data page to single uncompressed array. The TIDs are
100+
* returned in ascending order.
101+
*
102+
* advancePast is a hint, indicating that the caller is only interested in
103+
* TIDs > advancePast. To return all items, use ItemPointerSetMin.
104+
*
105+
* Note: This function can still return items smaller than advancePast that
106+
* are in the same posting list as the items of interest, so the caller must
107+
* still check all the returned items. But passing it allows this function to
108+
* skip whole posting lists.
100109
*/
101110
ItemPointer
102-
GinDataLeafPageGetItems(Page page, int *nitems)
111+
GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
103112
{
104113
ItemPointer result;
105114

106115
if (GinPageIsCompressed(page))
107116
{
108-
GinPostingList *ptr = GinDataLeafPageGetPostingList(page);
117+
GinPostingList *seg = GinDataLeafPageGetPostingList(page);
109118
Size len = GinDataLeafPageGetPostingListSize(page);
119+
Pointer endptr = ((Pointer) seg) + len;
120+
GinPostingList *next;
121+
122+
/* Skip to the segment containing advancePast+1 */
123+
if (ItemPointerIsValid(&advancePast))
124+
{
125+
next = GinNextPostingListSegment(seg);
126+
while ((Pointer) next < endptr &&
127+
ginCompareItemPointers(&next->first, &advancePast) <= 0)
128+
{
129+
seg = next;
130+
next = GinNextPostingListSegment(seg);
131+
}
132+
len = endptr - (Pointer) seg;
133+
}
110134

111-
result = ginPostingListDecodeAllSegments(ptr, len, nitems);
135+
if (len > 0)
136+
result = ginPostingListDecodeAllSegments(seg, len, nitems);
137+
else
138+
{
139+
result = NULL;
140+
*nitems = 0;
141+
}
112142
}
113143
else
114144
{

src/backend/access/gin/ginget.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
400400
BlockNumber rootPostingTree = GinGetPostingTree(itup);
401401
GinBtreeStack *stack;
402402
Page page;
403+
ItemPointerData minItem;
403404

404405
/*
405406
* We should unlock entry page before touching posting tree to
@@ -426,7 +427,8 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
426427
/*
427428
* Load the first page into memory.
428429
*/
429-
entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
430+
ItemPointerSetMin(&minItem);
431+
entry->list = GinDataLeafPageGetItems(page, &entry->nlist, minItem);
430432

431433
entry->predictNumberResult = stack->predictNumber * entry->nlist;
432434

@@ -558,7 +560,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, ItemPointerData advan
558560
continue;
559561
}
560562

561-
entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
563+
entry->list = GinDataLeafPageGetItems(page, &entry->nlist, advancePast);
562564

563565
for (i = 0; i < entry->nlist; i++)
564566
{

src/include/access/gin_private.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
692692
IndexTuple itup, int *nitems);
693693

694694
/* gindatapage.c */
695-
extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems);
695+
extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
696696
extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
697697
extern BlockNumber createPostingTree(Relation index,
698698
ItemPointerData *items, uint32 nitems,

0 commit comments

Comments
 (0)