postgreSQL源码分析——索引的建立与使用——GIN索引(1)
2021SC@SDUSC
本篇博客主要讲解Gin索引的介绍和相关的组织结构
目录
- GIN索引介绍
- GIN扩展
- 实现扩展步骤
- GIN索引组织结构
- 相关数据结构
- GISTPageOpaqueData
- GISTENTRY
- GinMetaPageData
GIN索引介绍
GIN(Generalized Inverted Index, 通用倒排索引) 是一个存储对(key, posting list)集合的索引结构,其中key是一个键值,而posting list 是一组出现过key的位置。如(‘hello’, ‘14:2 23:4’)中,表示hello在14:2和23:4这两个位置出现过,在PG中这些位置实际上就是元组的tid(行号,包括数据块ID(32bit),以及item point(16 bit) )。
在表中的每一个属性,在建立索引时,都可能会被解析为多个键值,所以同一个元组的tid可能会出现在多个key的posting list中。
通过这种索引结构可以快速的查找到包含指定关键字的元组,因此GIN索引特别适用于多值类型的元素搜索,比如支持全文搜索,数组中元素的搜索,而PG的GIN索引模块最初也是为了支持全文搜索而开发的。
GIN扩展
GIN是一个开放的索引接口,所以它不仅适用于已经存在的如数组、全文检索等数据类型,同样也可以扩展支持更多的数据类型。
在PG9.0版本中,定义一个GIN访问方法所要做的就是实现5个用户定义的方法,这些方法定义了键值、键值与键值之间的关系、被索引值、能够使用索引的查询以及部分匹配。
这些方法是:
1.compare方法:比较两个键值a和b,然后返回一个整数值,返回负值表示a < b,返回0表示a = b,返回正值表示a > b。
其函数原型如下:
int compare(Datum a, Datum b)
2.extractValue方法:根据参数inputValue生成一个键值数组,并返回其指针,键值数组中元素的个数存放在另一个参数nkeys中。
其函数原型如下:
Datum *extractValue(Datum inputValue, int32 *nkeys)
3.extractQuery方法:根据参数query生成一个用于查询的键值数组,并返回其指针。
函数原型如下:
Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data)
extractQuery通过参数n指定的操作符策略号来决定query的数据类型以及需要提取的键值,返回键值数组的长度存放在nkeys参数中。
如果query中不包含键值,则nkeys可以为0或者-1:
nkeys = 0 表示索引中所有值都满足查询,将执行完全索引扫描(查询null时是这样); nkeys = -1 表示索引中没有键值满足查询,跳过索引扫描。
在部分匹配时,输出参数pmatch记录返回的键值数组中的每一个键值是否请求部分匹配。
输出参数extra_data用来向consistent和comparPartial方法传递用户自定义需要的数据。
4. consistent方法:用于检查索引值是否满足查询,
其函数原型如下:
bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck)
如果索引值满足查询则返回true,如果recheck = true,则返回true的索引还需要进一步的检查。具体过程如下图所示
recheck: 精确比较时recheck = false;否则recheck = true,通过索引找到的基表元组还需要进行是否满足操作符的检查(在TSVector类型时,如果key带有权值,则recheck = true)。
5. comparePartial方法:将部分匹配的查询与索引值进行比较,返回值为负值表示两者不匹配,但继续索引扫描;返回值为0表示两者匹配;返回值为正值表示停止扫描。
其函数原型如下:
int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)
实现扩展步骤
在PG中添加一种新的数据类型并且让GIN支持该数据类型,则需要完成以下步骤:
1.添加数据类型
2.为新数据类型实现并注册各种操作符所需要的函数,然后创建新类型的操作符
3.用CREATE OPERATOR CLASS为新的数据类型创建一个操作符类,该语句需要指定GIN索引所需要的5个支持函数
PG的GIN索引,内部实现了对于TSVector数据类型的支持,并提供了把TEXT类型转换成TSVector的接口,所以可以说PG的GIN索引支持TSVector和TEXT的数据类型。
GIN索引组织结构
GIN索引包括四个部分:
1.Entry:相当于GIN索引的一个元素,Entry可以理解为GIN中的一个键值
2.Entry Tree:在一些Entry上构建B-Tree
3.Posting Tree:在一个Entry出现的物理位置构建的B-Tree
4.Posting List:一个Entry出现的物理位置的列表
GIN索引包含一个构建在Entry上的B-Tree索引,“Entry Tree”的内部节点与B-Tree一样,而叶子节点的索引项指针指向不同。在GIN索引中叶子节点上,指针指向分为两种情况:
1.如果Entry所出现的物理位置大于TOAST_INDEX_TARGET指定的值,则在这些位置上构建Posting Tree
2.如果小于索引项指针直接指向 Posting List
可以根据图示来更好的理解
相关数据结构
GISTPageOpaqueData
关于GIST索引页面的相关数据结构
typedef struct GISTPageOpaqueData
{PageGistNSN nsn; /* 记录页面分割*/BlockNumber rightlink; /* 指向下一个节点的右指针 */uint16 flags; /* 标志位 */uint16 gist_page_id; /* GIST索引的页号 */
} GISTPageOpaqueData;
GISTENTRY
Entry的相关数据结构
typedef struct GISTENTRY
{Datum key;Relation rel;Page page;OffsetNumber offset; //在页面的偏移量bool leafkey;//子节点
} GISTENTRY;
GinMetaPageData
typedef struct GinMetaPageData
{BlockNumber head;//待建立的索引页的链头BlockNumber tail;//待建立的索引页的链尾uint32 tailFreeSize;//尾部剩余空间BlockNumber nPendingPages;//挂起列表的块号int64 nPendingHeapTuples;//挂起列表的堆元组数//相关的统计数据BlockNumber nTotalPages;BlockNumber nEntryPages;BlockNumber nDataPages;int64 nEntries;int32 ginVersion;//gin索引的版本
} GinMetaPageData;
postgreSQL源码分析——索引的建立与使用——GIN索引(1)相关推荐
- PostgreSQL源码分析
PostgreSQL源码结构 PostgreSQL的使用形态 PostgreSQL采用C/S(客户机/服务器)模式结构.应用层通过INET或者Unix Socket利用既定的协议与数据库服务器进行通信 ...
- postgreSQL源码分析——索引的建立与使用——GIST索引(2)
2021SC@SDUSC 本篇博客主要讲解GiST索引创建以及删除的相关函数 这里写目录标题 GIST创建 相关数据结构 GISTBuildState GISTInsertStack gistbuil ...
- postgreSQL源码分析——索引的建立与使用——Hash索引(3)
2021SC@SDUSC 上一篇博客讲了关于Hash索引创建与插入的相关函数,这一篇博客讲述关于溢出页的操作函数以及Hash表的扩展相关的函数. 目录 溢出页的分配和回收 _hash_addovflp ...
- postgreSQL源码分析——索引的建立与使用——Hash索引(2)
2021SC@SDUSC 目录 Hash索引创建 hashbuild函数 _hash_init函数 Hash索引的插入 hashinsert函数 _hash_doinsert函数 总结 Hash索引创 ...
- postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)
2021SC@SDUSC 目录 上层操作函数 index_open index_beginscan() index_create() indexcmd.c 下层接口函数 IndexScanDescDa ...
- postgreSQL源码分析——索引的建立与使用——GIN索引(3)
2021SC@SDUSC 本篇博客继续讲解GIN索引创建和插入相关的函数,并讲解GIN索引的查询过程 目录 GIN索引的创建 ginbuild 插入函数 ginEntryInsert GIN索引查询 ...
- postgreSQL源码分析——索引的建立与使用——Hash索引(1)
2021SC@SDUSC 目录 Hash索引 Hash索引原理 Hash表 Hash索引结构 Hash的页面结构 元页 桶页,溢出页,位图页 和B-Tree相比的优缺点 优点 缺点 总结 Hash索引 ...
- postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(1)
2021SC@SDUSC 目录 概述 管理索引的系统表 记录索引相关的系统表 与索引系统表相关的后端源码 索引的操作函数 上层操作函数 下层接口函数 概述 索引是指按表中某些关键属性或表达式建立元组的 ...
- postgreSQL源码分析——索引的建立与使用——总结篇
2021SC@SDUSC 在小组中我负责索引的建立与使用的相关部分,在此一共写了16篇相关的分析报告,着重分析各种索引的操作和管理方法,以及分析了PG中四种最重要的索引B-Tree索引,Hash索引, ...
- postgreSQL源码分析——索引的建立与使用——B-Tree索引(3)
2021SC@SDUSC 目录 B-Tree的插入 bt_insert _bt_doinsert BTInsertStateData _bt_search函数 _bt_moveright函数 B-Tr ...
最新文章
- Vue从Hello World到打包(后端适读)
- Linux信号列表(sigint,sigtstp..)
- 【Python学习系列十三】Python机器学习库scikit-learn实现逻辑回归
- TClientDataSet[28]: 读写其他格式的 XML 文件
- 【STM32】通用定时器(TIM2到TIM5)
- java封装 1210 速记
- Go内存分配跟踪调优
- PoostgreSQL在Windows平台安装失败的解决
- word 中快速加入序号等符号
- C#编写一个控制台程序,输入一个日期,输出这一天是星期几。
- OpenStack部署(未完成)
- 联发科MT6797/Helio X20软件用户手册资料介绍
- yolov4用1050ti_Windows下基于VS2019|Opencv4.2.0|CUDA10.0|YOLOv4
- 极客日报:腾讯《王者荣耀》禁止未满12周岁用户充值;B站发布16款新品游戏;华为注册姚安娜商标被驳回
- oracle函数笔记
- 如何在Abaqus中用扫掠的方法画六面体网格
- 使用ECS和OSS搭建个人网盘
- Spring框架快速入门(Spring超全面讲解)
- HTB打靶日记:Bashed
- [hdu-1814] Peaceful Commission题解
热门文章
- python课后题答案第一章_python核心编程课后习题解答第一章
- 【clickhouse】flink jdbc 方式写入 clickhouse 报错 request to {}->http://xxx:8123: Broken pipe
- 95-910-170-源码-FlinkSQL-Flink SQL 中的流和动态表
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint
- 【Spring】Spring事务失效的 8 大原因
- Spark中RDD与DataFrame与DataSet的区别与联系
- 【ES】Mac 下安装ES 报错 Failed to create native process factories for Machine Learning
- 【Flink】Flink on RocksDB 参数调优指南
- 《spring-boot学习》-12-@controller和@RestController的区别?
- Caused by: java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode(