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

2021SC@SDUSC
本篇博客主要讲解GiST索引创建以及删除的相关函数

GIST创建

GIST创建相关函数主要在gistbuild.c文件中,我们来分析一下重要的函数和数据结构

相关数据结构

GISTBuildState

typedef struct
{
   
	Relation	indexrel;//索引关系
	Relation	heaprel;//堆关系
	GISTSTATE  *giststate;

	int64		indtuples;		/* 索引元组数量 */
	int64		indtuplesSize;	/* 所有索引元组的总大小*/

	Size		freespace;		/*页面上空闲空间*/

	/*
在缓冲构建期间使用的额外数据结构。
	 */
	GISTBuildBuffers *gfbb;//“gfbb”包含与管理构建缓冲区相关的信息。
	HTAB	   *parentMap;//内部节点的父节点

	GistBufferingMode bufferingMode;
} GISTBuildState;

GISTInsertStack

在插入索引元组中,会生成 GISTInsertStack的数据结构,这对于GIST元组的插入有重要作用

typedef struct GISTInsertStack
{
   
	
	BlockNumber blkno;//当前页面的块号
	Buffer		buffer;//当前页面所在的缓冲区
	Page		page;//当前页面的页号

	GistNSN		lsn;//用于确定是否更新或分裂

	bool		retry_from_parent;//如果设置该值为真,那么将拆分页面,我们需要查找目标,需要从父节点重试

	OffsetNumber downlinkoffnum;//指向下行链接的偏移量

	struct GISTInsertStack *parent;//指向父节点
} GISTInsertStack;

gistbuild函数

GIST建立主要使用gistbuild函数,通过分析该函数,先将主要流程总结如下:
1.初始化索引状态信息
2.根据字符串选取缓冲模式
3.初始化根页面,并申请缓冲区进行GIST的创建
4.创建临时环境
5.扫描堆元组,进行GIST的元组的插入,会调用到gistdoinsert的相关函数
6.当构建完成时,释放缓冲区和临时环境

 IndexBuildResult *gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
{
   
	IndexBuildResult *result;//声明相关的变量
	double		reltuples;
	GISTBuildState buildstate;
	Buffer		buffer;
	Page		page;
	MemoryContext oldcxt = CurrentMemoryContext;
	int			fillfactor;

	buildstate.indexrel = index;//给buildstate数据结构中的变量赋值
	buildstate.heaprel = heap;
	if (index->rd_options)
	{
   
		/* 从字符串中获取缓冲模式*/
		GiSTOptions *options = (GiSTOptions *) index->rd_options;
		char	   *bufferingMode = (char *) options + options->bufferingModeOffset;

		if (strcmp(bufferingMode, "on") == 0)//当bufferingmode=on时为GIST_BUFFERING_STATS
			buildstate.bufferingMode = GIST_BUFFERING_STATS;
		else if (strcmp(bufferingMode, "off") == 0)
			buildstate.bufferingMode = GIST_BUFFERING_DISABLED;
		else
			buildstate.bufferingMode = GIST_BUFFERING_AUTO;

		fillfactor = options->fillfactor;
	}
	else
	{
   
		/*
	    当索引太大而无法放入缓存,则切换到缓冲模式
		 */
		buildstate.bufferingMode = GIST_BUFFERING_AUTO;
		fillfactor = GIST_DEFAULT_FILLFACTOR;
	}
	/* 计算页面剩余空间 */
	buildstate.freespace = BLCKSZ * (100 - fillfactor) / 100;

	/*
	索引关系需要只调用一次,否则报错
	 */
	if (RelationGetNumberOfBlocks(index) != 0)
		elog(ERROR, "index \"%s\" already contains data",
			 RelationGetRelationName(index));

	buildstate.giststate = initGISTstate(index);

//创建一个临时上下文,每个元组重置处理
	buildstate.giststate->tempCxt = createTempGistContext();

	/* 初始化根页面*/
	buffer = gistNewBuffer(index);
	Assert(BufferGetBlockNumber(buffer) == GIST_ROOT_
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL 中的 SP-GiST 是一种通用的空间数据结构,它可以用于实现各种数据类型的索引,例如文本、图像等非空间数据类型。SP-GiST 索引相对于 B-tree 索引来说,具有更好的可扩展性和更高的查询效率,特别是在处理大规模数据集时,表现更为优异。 下面是在 PostgreSQL使用 SP-GiST 索引的一些步骤: 1. 创建扩展 在使用 SP-GiST 索引之前,需要先创建 SP-GiST 扩展。可以使用如下 SQL 语句创建 SP-GiST 扩展: ``` CREATE EXTENSION IF NOT EXISTS "spgist"; ``` 2. 创建索引 在创建 SP-GiST 索引时,需要指定 SP-GiST 算法的名称和需要索引的列。例如,下面的 SQL 语句创建了一个 SP-GiST 索引,用于对表中的 jsonb 类型的列 data 进行索引: ``` CREATE INDEX idx_data_spgist ON tablename USING spgist(data); ``` 3. 查询优化 在使用 SP-GiST 索引时,需要根据具体的业务需求进行查询优化。通常情况下,可以使用 SP-GiST 索引提供的查询算子来实现高效的查询。例如,对于 jsonb 类型的列 data,可以使用 SP-GiST 索引提供的 @> 查询算子来进行查询: ``` SELECT * FROM tablename WHERE data @> '{"key": "value"}'; ``` 这样可以快速地查询出符合条件的记录。 总的来说,SP-GiST 索引可以用于优化各种非空间数据类型的查询,例如文本、图像、JSON 等。在使用 SP-GiST 索引时,需要根据具体的业务需求进行查询优化,以实现最佳的查询效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值