2021SC@SDUSC
本篇博客主要讲解GiST索引查询的相关函数,并结合具体实例来介绍GIST的使用过程
GIST索引查询
GIST的相关搜索查询在9.0版本使用了Stack的相关结构,而在我下载12.0版本上查询相关的数据结构改成了与堆相关的数据结构,很显然这样加快了搜索的速度。
GISTSearchHeapItem
typedef struct GISTSearchHeapItem
{
ItemPointerData heapPtr;
bool recheck; /*T如果合格需要重新检查*/
bool recheckDistances; /* T在距离内必须重新检查 */
HeapTuple recontup; /*堆元组用于扫描索引 */
OffsetNumber offnum; /* 记录在页中的偏移量来标记元祖 */
} GISTSearchHeapItem;
GISTSearchItem
搜索到的堆元组的相关数据结构,每个元组都有该数据结构
typedef struct GISTSearchItem
{
pairingheap_node phNode;
BlockNumber blkno; /* 索引页号*/
union
{
GistNSN parentlsn; /*存储parentlsn来记录是否父页面发生分裂*/
GISTSearchHeapItem heap; /* 索引查询堆元组 */
} data;
IndexOrderByDistance distances[FLEXIBLE_ARRAY_MEMBER];
} GISTSearchItem;
gistScanPage函数
GIST的查询有index scan和bitmap scan两种方法,该函数是在一个页面中寻找匹配的数据,其中分为多种情况,如果是叶子节点会将匹配的数据放入队列中,如果不是则会将匹配的元组指向的子节点放入队列中
static void
gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
IndexOrderByDistance *myDistances, TIDBitmap *tbm, int64 *ntids)
{
//查询相关信息的初始化
GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
GISTSTATE *giststate = so->giststate;
Relation r = scan->indexRelation;
Buffer buffer;
Page page;
GISTPageOpaque opaque;
OffsetNumber maxoff;
OffsetNumber i;
MemoryContext oldcxt;
Assert(!GISTSearchItemIsHeap(*pageItem));
buffer = ReadBuffer(scan->indexRelation, pageItem->blkno);
LockBuffer(buffer, GIST_SHARE);
PredicateLockPage(r, BufferGetBlockNumber(buffer), scan->xs_snapshot);
gistcheckpage(scan->indexRelation, buffer);
page = BufferGetPage(buffer);
TestForOldSnapshot(scan->xs_snapshot, r, page);
opaque = GistPageGetOpaque(page);
/*
检查是否需要遵循右侧指针,通过查看父页面的数据结构中的parentisn,如果小于Nsn,那么就要用右指针
*/
if (!XLogRecPtrIsInvalid(pageItem->data.parentlsn) &&
(GistFollowRight(page) ||
pageItem->data.parentlsn < GistPageGetNSN(page)) &&
opaque->rightlink != InvalidBlockNumber /* sanity check */ )
{
/* 页面分割,使用右指针*/
GISTSearchItem *item;
Assert(myDistances != NULL);
oldcxt = MemoryContextSwitchTo(so->queueCxt);
/*为新分裂的页面创造新的 GISTSearchItem数据结构*/
item = palloc(SizeOfGISTSearchItem(scan->numberOfOrderBys));
item->blkno = opaque->rightlink;
item->data.parentlsn = pageItem