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)相关推荐

  1. PostgreSQL源码分析

    PostgreSQL源码结构 PostgreSQL的使用形态 PostgreSQL采用C/S(客户机/服务器)模式结构.应用层通过INET或者Unix Socket利用既定的协议与数据库服务器进行通信 ...

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

    2021SC@SDUSC 本篇博客主要讲解GiST索引创建以及删除的相关函数 这里写目录标题 GIST创建 相关数据结构 GISTBuildState GISTInsertStack gistbuil ...

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

    2021SC@SDUSC 上一篇博客讲了关于Hash索引创建与插入的相关函数,这一篇博客讲述关于溢出页的操作函数以及Hash表的扩展相关的函数. 目录 溢出页的分配和回收 _hash_addovflp ...

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

    2021SC@SDUSC 目录 Hash索引创建 hashbuild函数 _hash_init函数 Hash索引的插入 hashinsert函数 _hash_doinsert函数 总结 Hash索引创 ...

  5. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)

    2021SC@SDUSC 目录 上层操作函数 index_open index_beginscan() index_create() indexcmd.c 下层接口函数 IndexScanDescDa ...

  6. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(1)

    2021SC@SDUSC 目录 概述 管理索引的系统表 记录索引相关的系统表 与索引系统表相关的后端源码 索引的操作函数 上层操作函数 下层接口函数 概述 索引是指按表中某些关键属性或表达式建立元组的 ...

  7. postgreSQL源码分析——索引的建立与使用——总结篇

    2021SC@SDUSC 在小组中我负责索引的建立与使用的相关部分,在此一共写了16篇相关的分析报告,着重分析各种索引的操作和管理方法,以及分析了PG中四种最重要的索引B-Tree索引,Hash索引, ...

  8. postgreSQL源码分析——索引的建立与使用——B-Tree索引(3)

    2021SC@SDUSC 目录 B-Tree的插入 bt_insert _bt_doinsert BTInsertStateData _bt_search函数 _bt_moveright函数 B-Tr ...

  9. postgreSQL源码分析——索引的建立与使用——B-Tree索引(2)

    2021SC@SDUSC 目录 B-Tree建立过程 IndexAmRoutine BTBuildState BTWriteState btbuild() _bt_leafbuild _bt_load ...

最新文章

  1. 数字信号的最佳接收理论
  2. RabbitMQ 入门
  3. 360极速浏览器使用postman
  4. soa学习路线_Web服务安全性和SOA路线图的人为维度
  5. iis8 php mysql zend,强烈推荐windows 2012 iis8 fastcgi php5.2.17 zend mysql
  6. BZOJ2160 拉拉队排练
  7. 学习ajxa 必备插件
  8. 中兴服务器isac配置,中兴AC 配置手册V1.0.docx
  9. 韩波兄的好文:写给过去,现在和未来的自己
  10. 高通按键驱动(gpio) + 耳机插入检测
  11. 商学院学习笔记(2)
  12. SpringBoot系列之对Excel报表的校验提示
  13. 木瓜移动再求上市:毛利率走低、盈利能力弱,沈思“迷恋”相亲
  14. android 什么是有权查看使用情况的应用程序
  15. 友盟新浪微博授权提示“找不到文件C8998”的解决办法
  16. 网络通信详解-深入浅出
  17. 最新全国姓名报告出炉!
  18. ABBYY FineReader 15如何比较文档?
  19. presto获取上月第一天和最后一天、当月第一天
  20. android 点赞手型,在朋友圈,你是哪种点赞型人格?

热门文章

  1. linux串口查看mxser,Ubuntu8.04安装CP-168U的串口连接问题
  2. 【clickhouse】ClickHouse之DBA运维宝典
  3. 【Elasticsearch】 es join 多表关联如何设计
  4. 【java】Java 中的 Exchanger 线程同步使用方法 线程之间交换数据
  5. 【Elasticsearch】7.9 单字段支持的最大字符数
  6. 【Java】HashMap 和 Hashtable 的 6 个区别
  7. 【Kafka】Kafka 奇怪问题之无法用Java 客户端消费
  8. SQL解析利器General SQL Parser
  9. Spring : Factories这个是什么
  10. 【Janino】Janino介绍