mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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.
This commit is contained in:
parent
e20c70cb0f
commit
25b1dafab6
@ -96,19 +96,49 @@ static void dataPlaceToPageLeafSplit(Buffer buf,
|
|||||||
XLogRecData **prdata, Page lpage, Page rpage);
|
XLogRecData **prdata, Page lpage, Page rpage);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read all TIDs from leaf data page to single uncompressed array.
|
* Read TIDs from leaf data page to single uncompressed array. The TIDs are
|
||||||
|
* returned in ascending order.
|
||||||
|
*
|
||||||
|
* advancePast is a hint, indicating that the caller is only interested in
|
||||||
|
* TIDs > advancePast. To return all items, use ItemPointerSetMin.
|
||||||
|
*
|
||||||
|
* Note: This function can still return items smaller than advancePast that
|
||||||
|
* are in the same posting list as the items of interest, so the caller must
|
||||||
|
* still check all the returned items. But passing it allows this function to
|
||||||
|
* skip whole posting lists.
|
||||||
*/
|
*/
|
||||||
ItemPointer
|
ItemPointer
|
||||||
GinDataLeafPageGetItems(Page page, int *nitems)
|
GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
|
||||||
{
|
{
|
||||||
ItemPointer result;
|
ItemPointer result;
|
||||||
|
|
||||||
if (GinPageIsCompressed(page))
|
if (GinPageIsCompressed(page))
|
||||||
{
|
{
|
||||||
GinPostingList *ptr = GinDataLeafPageGetPostingList(page);
|
GinPostingList *seg = GinDataLeafPageGetPostingList(page);
|
||||||
Size len = GinDataLeafPageGetPostingListSize(page);
|
Size len = GinDataLeafPageGetPostingListSize(page);
|
||||||
|
Pointer endptr = ((Pointer) seg) + len;
|
||||||
|
GinPostingList *next;
|
||||||
|
|
||||||
result = ginPostingListDecodeAllSegments(ptr, len, nitems);
|
/* Skip to the segment containing advancePast+1 */
|
||||||
|
if (ItemPointerIsValid(&advancePast))
|
||||||
|
{
|
||||||
|
next = GinNextPostingListSegment(seg);
|
||||||
|
while ((Pointer) next < endptr &&
|
||||||
|
ginCompareItemPointers(&next->first, &advancePast) <= 0)
|
||||||
|
{
|
||||||
|
seg = next;
|
||||||
|
next = GinNextPostingListSegment(seg);
|
||||||
|
}
|
||||||
|
len = endptr - (Pointer) seg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
result = ginPostingListDecodeAllSegments(seg, len, nitems);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = NULL;
|
||||||
|
*nitems = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -400,6 +400,7 @@ restartScanEntry:
|
|||||||
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
||||||
GinBtreeStack *stack;
|
GinBtreeStack *stack;
|
||||||
Page page;
|
Page page;
|
||||||
|
ItemPointerData minItem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should unlock entry page before touching posting tree to
|
* We should unlock entry page before touching posting tree to
|
||||||
@ -426,7 +427,8 @@ restartScanEntry:
|
|||||||
/*
|
/*
|
||||||
* Load the first page into memory.
|
* Load the first page into memory.
|
||||||
*/
|
*/
|
||||||
entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
|
ItemPointerSetMin(&minItem);
|
||||||
|
entry->list = GinDataLeafPageGetItems(page, &entry->nlist, minItem);
|
||||||
|
|
||||||
entry->predictNumberResult = stack->predictNumber * entry->nlist;
|
entry->predictNumberResult = stack->predictNumber * entry->nlist;
|
||||||
|
|
||||||
@ -558,7 +560,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, ItemPointerData advan
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
|
entry->list = GinDataLeafPageGetItems(page, &entry->nlist, advancePast);
|
||||||
|
|
||||||
for (i = 0; i < entry->nlist; i++)
|
for (i = 0; i < entry->nlist; i++)
|
||||||
{
|
{
|
||||||
|
@ -692,7 +692,7 @@ extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
|
|||||||
IndexTuple itup, int *nitems);
|
IndexTuple itup, int *nitems);
|
||||||
|
|
||||||
/* gindatapage.c */
|
/* gindatapage.c */
|
||||||
extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems);
|
extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
|
||||||
extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
|
extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
|
||||||
extern BlockNumber createPostingTree(Relation index,
|
extern BlockNumber createPostingTree(Relation index,
|
||||||
ItemPointerData *items, uint32 nitems,
|
ItemPointerData *items, uint32 nitems,
|
||||||
|
Loading…
Reference in New Issue
Block a user