postgreSQL源码分析——索引的建立与使用——Hash索引(1)
2021SC@SDUSC
目录
- Hash索引
- Hash索引原理
- Hash表
- Hash索引结构
- Hash的页面结构
- 元页
- 桶页,溢出页,位图页
- 和B-Tree相比的优缺点
- 优点
- 缺点
- 总结
Hash索引
postgreSQL除了可以使用B-Tree索引,也可以使用Hash索引,Hash索引拥有更快的查询速率,我们本篇主要讲解一下Hash索引的原理并且比较它与B-Tree的区别,同时分析源码中关于Hash索引的相关的数据结构。
Hash索引原理
Hash表
哈希表也为散列表,其原理如下图所示
Hash索引的核心是构建一个Hash表,主要原理就是在Hash表中有一个Hash函数,通过查找键为参数,计算出映射到的桶号,将键值分配到各个桶中。然后仍然需要遍历桶中的内容,并仅返回具有适当哈希码的匹配ctid(行号)。由于存储的“hash code - ctid”对是有序的,因此可以高效地完成此操作。
同时Hash索引表可以分为静态Hash表和动态Hash表,静态Hash表不会增加桶的数目,而动态Hash表可以动态增加桶的数目。PostgreSQL则使用了动态Hash表的结构
Hash索引结构
每一个Hash索引结构如下所示,每一个Hash索引都有四种类型的页面,分别为元页,桶页,溢出页,位图页,接下来会介绍下关于Hash索引的相关的数据结构。
Hash的页面结构
Hash的页面结构与B-Tree相似,而其special space的字段填充为HashPageOpaqueData结构,我们从pg的源码找出该结构typedef struct HashPageOpaqueData
{BlockNumber hasho_prevblkno; /* 前一页的块号*/BlockNumber hasho_nextblkno; /* 下一页的块号*/Bucket hasho_bucket; /* 属于某个桶页的桶号*/uint16 hasho_flag; /* 标注该页的所属类型 */uint16 hasho_page_id; /* 该页的Hash索引Id*/
} HashPageOpaqueData;
元页
每个Hash索引都有一个元页,它是该索引的初始页面,它也不属于任何桶,它记录了Hash的版本号,Hash索引记录的索引元组数目,桶的信息,位图等相关信息,其他页的信息也与元页息息相关,我们来看一下pg源码中的元页的数据结构:
typedef struct HashMetaPageData
{uint32 hashm_magic; /*Hash表的magic号*/uint32 hashm_version; /* Hash版本号 */double hashm_ntuples; /*存储元组的数目*/uint16 hashm_ffactor; /* 与分裂有关*/uint16 hashm_bsize; /* 桶的大小*/uint16 hashm_bmsize; /* 位图的大小,必须是2的幂次 */uint16 hashm_bmshift; /* log2(位图数组的大小) */uint32 hashm_maxbucket; /* 可用的最大桶号 */uint32 hashm_highmask; /* 桶号的高16位掩码*/uint32 hashm_lowmask; /* 桶号的低十六位掩码 */uint32 hashm_ovflpoint; /* 分裂次数 */uint32 hashm_firstfree; /* 第一个可能的溢出页号*/uint32 hashm_nmaps; /* 位图的个数 */RegProcedure hashm_procid; /* Hash函数的OID*/uint32 hashm_spares[HASH_MAX_SPLITPOINTS]; /* 总共分配的溢出页数目 */BlockNumber hashm_mapp[HASH_MAX_BITMAPS]; /*位图的块号*/
} HashMetaPageData;
桶页,溢出页,位图页
桶页:Hash表有多个桶组成,每个桶有一个或多个页组成,每一个桶的第一个页叫做桶页,其他页面称作溢出页,桶页成2的幂次分配,当在元页中记录的splitpoint增加时,桶页成2的幂次增长。
溢出页:当一个元组的内容超过桶页的大小时,需要给该桶增加一个溢出页,溢出页和桶页是通过双向链链接起来的。
位图页:用于管理Hash索引的溢出页和位图页本身的使用情况,如果某个溢出页上的元组都被移除,则将溢出页回收。位图的页面格式如下图所示,他是用比特位来表示位图页或者溢出页是否可用,0不可用,1可用
和B-Tree相比的优缺点
优点
Hash索引的执行效率很快,时间复杂度低,,索引检索一次到位你,不需要和B-Tree索引一样由根节点再到叶子节点,可以用于等值查询,以及btree索引不支持的大字段类型
缺点
1.由于Hash索引指向的数据是无序的,Hash索引不能进行范围查询,而B+树可以。
2.Hash索引无法被用来避免数据的排序操作。Hash索引中存放的是经过Hash计算之后的Hash值,而且Hash值得大小关系不一定和Hash运算前的键值完全一样。
3当产生大量的Hash冲突时,Hash索引的执行效率会降低,浪费多次数据的访问。
总结
postgreSQL的Hash 索引的相关算法主要是由Margo Seltzer and Ozan Yigit提出的,使用动态索引表,页面结构由元页,位图页,桶页,溢出页来共同组成并介绍了相关数据结构,下一篇我们进行对于Hash索引建立的相关讲解。
postgreSQL源码分析——索引的建立与使用——Hash索引(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源码分析——索引的建立与使用——各种索引类型的管理和操作(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 ...
- postgreSQL源码分析——索引的建立与使用——B-Tree索引(2)
2021SC@SDUSC 目录 B-Tree建立过程 IndexAmRoutine BTBuildState BTWriteState btbuild() _bt_leafbuild _bt_load ...
最新文章
- 数字信号的最佳接收理论
- RabbitMQ 入门
- 360极速浏览器使用postman
- soa学习路线_Web服务安全性和SOA路线图的人为维度
- iis8 php mysql zend,强烈推荐windows 2012 iis8 fastcgi php5.2.17 zend mysql
- BZOJ2160 拉拉队排练
- 学习ajxa 必备插件
- 中兴服务器isac配置,中兴AC 配置手册V1.0.docx
- 韩波兄的好文:写给过去,现在和未来的自己
- 高通按键驱动(gpio) + 耳机插入检测
- 商学院学习笔记(2)
- SpringBoot系列之对Excel报表的校验提示
- 木瓜移动再求上市:毛利率走低、盈利能力弱,沈思“迷恋”相亲
- android 什么是有权查看使用情况的应用程序
- 友盟新浪微博授权提示“找不到文件C8998”的解决办法
- 网络通信详解-深入浅出
- 最新全国姓名报告出炉!
- ABBYY FineReader 15如何比较文档?
- presto获取上月第一天和最后一天、当月第一天
- android 点赞手型,在朋友圈,你是哪种点赞型人格?
热门文章
- linux串口查看mxser,Ubuntu8.04安装CP-168U的串口连接问题
- 【clickhouse】ClickHouse之DBA运维宝典
- 【Elasticsearch】 es join 多表关联如何设计
- 【java】Java 中的 Exchanger 线程同步使用方法 线程之间交换数据
- 【Elasticsearch】7.9 单字段支持的最大字符数
- 【Java】HashMap 和 Hashtable 的 6 个区别
- 【Kafka】Kafka 奇怪问题之无法用Java 客户端消费
- SQL解析利器General SQL Parser
- Spring : Factories这个是什么
- 【Janino】Janino介绍