postgreSQL源码分析——索引的建立与使用——GIST索引(3)

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值