哈希索引(PostgreSQL 14 Internals翻译版)

news2024/11/13 7:13:08

概览

哈希索引提供了根据特定索引键快速查找tuple ID (TID)的功能。粗略地说,它只是一个存储在磁盘上的哈希表。哈希索引唯一支持的操作是根据相等条件进行搜索

当一个值插入到索引中时,将计算索引键的哈希函数。PostgreSQL哈希函数返回32位或64位整数;这些值中最低的几个位用作相应桶的编号。将TID和键的哈希码添加到所选的桶中。键本身不存储在索引中,因为这样处理固定长度的小值更方便。

索引的哈希表是动态扩展的。桶的最小数量是两个。随着索引元组数量的增长,其中一个存储桶被分成两个。该操作使用了多一位哈希码,因此元素仅在拆分产生的两个桶之间重新分布;哈希表的其他桶的组成保持不变。

索引搜索操作计算索引键和对应桶号的哈希函数。在所有桶内容中,搜索将只返回那些与键的哈希码对应的TID。由于bucket元素是按键的哈希码排序的,因此二进制搜索可以非常有效地返回匹配的TID。

由于键不存储在哈希表中,因此索引访问方法可能会由于哈希冲突而返回冗余的tid。因此,索引引擎必须重新检查访问方法获取的所有结果。出于同样的原因,不支持仅索引扫描

页面布局

与常规哈希表不同,哈希索引存储在磁盘上。因此,必须将所有数据安排到页中,最好是这样一种方式,即索引操作(搜索、插入、删除)需要访问尽可能少的页。

哈希索引使用四种类型的页面:

  • metapage—提供索引“目录”的页零
  • bucket pages—索引的主要页面,每个bucket一个
  • overflow pages—当主桶页不能容纳所有元素时使用的附加页
  • bitmap pages—包含位数组的页面,用于跟踪已被释放并可被重用的溢出页面

我们可以使用pageinspect扩展查看索引页。

让我们从一张空表开始:

在这里插入图片描述

我已经分析了表,因此创建的索引将具有尽可能小的大小;否则,将根据表包含10个页面的假设选择桶的数量。

索引包含四个页面:元页面,两个桶页面和一个位图页面(一次创建以备将来使用):

在这里插入图片描述

元页面包含有关索引的所有控制信息。我们现在只对几个值感兴趣:

在这里插入图片描述

每个桶的估计行数显示在ffactor字段中。该值是根据块大小和fillfactor存储参数值计算得出的。通过绝对统一的数据分布和没有散列冲突,您可以使用更高的填充因子值,但在实际数据库中,它会增加页面溢出的风险。

对于散列索引来说,最糟糕的情况是当一个键被重复多次时,数据分布出现很大的倾斜。由于哈希函数将返回一个相同的值,因此所有数据将被放置到相同的桶中,并且增加桶的数量不会有帮助。

现在索引为空,如ntuples字段所示。让我们通过插入具有相同索引键值的多行来导致桶页溢出。索引中出现溢出页:

在这里插入图片描述

综合所有页面的统计数据,桶0是空的,而所有的值都被放到了桶1中:其中一些位于主页面,不适合的可以在溢出页中找到。

在这里插入图片描述

很明显,如果同一个bucket的元素分布在几个页面上,性能将受到影响。如果数据分布是均匀的,散列索引将显示最佳结果。

现在让我们来看看如何分割桶。当索引中的行数超过可用桶的估计因子值时,就会发生这种情况。这里我们有两个桶,因子是307,所以它将在第615行插入索引时发生:

在这里插入图片描述
maxbucket值已经增加到2:现在我们有三个桶,编号从0到2。但是,尽管我们只添加了一个桶,页面的数量却翻了一番:

在这里插入图片描述
其中一个新页面由bucket 2使用,而另一个页面保持空闲状态,一旦出现就会被bucket 3使用。

在这里插入图片描述
在这里插入图片描述
因此,从操作系统的角度来看,哈希索引是快速增长的,尽管从逻辑的角度来看哈希表是逐渐增长的。

为了在一定程度上平衡这种增长并避免一次分配过多的页面,从第10次增加开始,将页面分配为四个相等的批次,而不是一次分配所有的页面。

元页面的另外两个字段实际上是位掩码,提供了桶地址的详细信息:

在这里插入图片描述
桶号由与高掩码对应的哈希码位定义。但是如果接收到的桶号不存在(超过maxbucket),则采用低掩码位。在这个特殊的例子中,我们取两个最低的位,得到0到3的值;但是如果我们得到3,我们只会取一个最低的位,也就是说,用桶1代替桶3。

每次大小增加一倍时,新的桶页被分配为单个连续块,而溢出页和位图页则根据需要插入这些片段之间。元页面保留插入到备件数组中每个块中的页面数,这使我们有机会使用简单的算术根据桶号计算其主页的数量。

在这个特殊的例子中,第一次增加之后插入了两个页面(一个位图页面和一个溢出页面),但是在第二次增加之后没有发生新的添加:

在这里插入图片描述
当指向死元组的指针被删除时,索引页中的空间将被释放。它发生在页面修剪期间(在尝试将元素插入完全填充的页面时触发)或执行常规真空时。

但是,哈希索引不能缩小:一旦分配,索引页将不会返回给操作系统。主页被永久地分配到它们的bucket中,即使它们根本不包含任何元素;清除的溢出页在位图中被跟踪,并且可以被重用(可能由另一个桶)。减小索引物理大小的唯一方法是使用REINDEX或
VACUUM FULL命令。

查询计划没有索引类型的指示:

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM - Springboot - MyBatis-Plus 全栈体系(三十六)

第八章 项目实战 四、后台功能开发 3. 头条模块开发 3.1 登陆验证和保护 3.1.1 需求描述 客户端在进入发布页前、发布新闻前、进入修改页前、修改前、删除新闻前先向服务端发送请求携带 token 请求头后端接收 token 请求头后,校验用户登录是否过期并做响应前端根…

Openssl数据安全传输平台009:加密理论基础:哈希/非对称加密RSA/对称加密AES

文章目录 0. 代码仓库代码编译时候可能出现的错误 1. 哈希1.1 哈希算法的种类:1.2 使用的头文件1.3 哈希算法API1.3.1 详解md5 API1.3.2 sha1/sha224/sha256/sha384/sha512常用API 1.5 sha1代码测试1.4 在VS中添加预处理器定义1.5 哈希算法C代码封装的思路 2. 非对称加密RSA2.1…

uniapp 单选框以及多选框样式更改

radio以及checkbox默认样式不符合自身需求时,根据自身需求更改样式,以下是自身的示例: 单选: 多选: 由于uniapp自身包含了一套默认的样式,所以如果不想全局更改只想在某个单据页面使用的话,就…

Redis3.2.12版本服务器迁移

1.新机器更新yum源 yum -y update 2.新机器安装redis数据库 yum install redis 3.新机器下载fedora的epel仓库 systemctl enable redis 4.将旧机器上的/etc/redis.conf拷贝到新机器的/config目录下 scp -r -P22 redis.config root162.32.196.57:/config/redis.config 5.新机器启…

CentOS 编译安装TinyXml2

安装 TinyXml2 Git 源码下载地址:https://github.com/leethomason/tinyxml2 步骤1:首先,你需要下载tinyxml2的源代码。你可以从Github或者源代码官方网站下载。并上传至/usr/local/source_code/ 步骤2:下载完成后,需要将源代码解…

LrC 13 ACR 16:点颜色

Adobe Lightroom Classic 13( 2023 年 10 月版)及 Adobe Camera Raw 16 新增的点颜色 Point Color功能可以方便、精准地调整图像上的颜色。 LrC:修改照片/混色器/点颜色 Develop/Color Mixer/Point Color ACR:编辑/混色器/点颜色 …

希捷推出Exos系列24TB硬盘:配备增强型缓存 性能提高三倍

希捷推出了全新的Exos 24TB硬盘。其基于传统的CMR构建,为3.5英寸规格,转速为7200 RPM。 同时,Exos系列24TB硬盘拥有10片磁盘,每片磁盘的容量为2.4TB,是希捷存储密度最高的硬盘,适用于超大规模企业和数据中心…

最新Jn建站系统2.0 已集成各类源码 【附视频安装教程】

附视频安装教程|已集成各类源码 目前已集成的网站: 1.发卡网(最新) 2.代刷网(无需授权) 3. 博客网(自带模板) 4.易支付(稳定版) 5.个人导航网(简洁) 6.代理查询网 7.留言网 8.匿名网 9.表白墙(最新) 10.抽奖网 11.源码站 12.z-blog博客程序 13.织梦CM…

Ubuntu Linux下如何搭建并安装EDK2

本教程全程手动下载安装: 1、官网下载EDK2安装包(这里下载当前最新版) ---- 2023.10.23 网址:https://sourceforge.net/projects/edk2/files/UDK2015_Releases/UDK2015/UDK2015.Complete.MyWorkSpace.zip 2、解压 unzip UDK2015.Complete.MyWorkSpace…

Android 实现资源国际化(多语言)

目录 一、介绍 二、字符串资源 三、图片资源 四、日期和时间格式 五、其他 六、应用内切换语言 七、资源文件命名规则 一、介绍 Android国际化(多语言)是一种开发技术,旨在使Android应用程序能够在「不同语言和文化环境」下运行,并为用户提供本地…

vue3中使用vue3-pdf-app和使用浏览器内置的PDF插件浏览器PDF文件

文章目录 先准备一个PDF使用浏览器内置的PDF插件预览PDF在HTML中使用浏览器插件预览PDFVscode使用插件发布服务后直接通过URL地址访问PDF可使用的浏览器 在vue3项目中预览PDF文件vue3项目也是可以通过URL地址访问文件的vue3中使用浏览器内置的PDF插件预览PDF代码如下所示&#…

单窗口单IP适合炉石传说游戏么?

游戏道具制作在炉石传说中是一个很有挑战的任务,但与此同时,它也是一个充满机遇的领域。在这篇文章中,我们将向您展示如何在炉石传说游戏中使用动态包机、多窗口IP工具和动态IP进行游戏道具制作。 作者与主题的关系:作为一名热爱炉…

【分布式】大模型分布式训练入门与实践 - 04

大模型分布式训练 数据并行-Distributed Data Parallel1.1 背景1.2 PyTorch DDP1) DDP训练流程2)DistributedSampler3)DataLoader: Parallelizing data loading4)Data-parallel(DP)5)DDP原理解析…

nodejs+vue 视频网站的设计与实现

该设计划分为七大模块,包括用户的系统管理、其他管理和视频管理三部分, 和管理管理员的视频、其他管理、系统管理和用户管理四部分。目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关…

【虚幻引擎UE】UE4/UE5 基于2D屏幕坐标获取场景3D坐标 射线检测(蓝图/C++)

UE4/UE5 基于2D屏幕坐标获取场景3D坐标 一、射线检测1)定义1)射线与3D场景中的物体交互的流程2)射线检测蓝图函数3)蓝图实现根据鼠标点击位置获取场景中的坐标值4)根据相机中心点获取场景中的坐标值5)射线检…

迅为RK3588开发板Android12双摄同时显示

要支持双摄同时显示需对源码做如下修改,修改文件 hardware/rockchip/camera/Camera3HALModule.cpp 注释掉下面函数中的部分代码即可。 测试 双摄同时显示需要双摄 app,在网盘资料下载测试 APK,然后使用 adb 安装测试 APK, 启动…

hive窗口函数记录

记录工作中和学习中的窗口函数,方便以后使用,本记持续更新和完善,版本:231019 文章目录 1.什么是窗口函数2.窗口函数的表达式3.窗口函数的类型1) 排名函数2) 聚合函数3) 跨行取值函数 4.[frame…

中英文双语言海外微盘交易源码 微盘交易源码 虚拟币微盘交易系统源码 支持产品数据

Rockefeller微交易源码/双语言海外微盘完整源码/带单控 测试环境:宝塔、Linux、PHP7.3、MySQL5.6 根目录 public,伪静态 larvael5,默认文档:index.html修改为第一个,不然会报404 k线对接的是蜜蜂查:http…

平衡二叉树(AVL)【java实现+图解】

目录 一、平衡二叉树(AVL) 二、平衡二叉树的四种旋转 1.右旋转 2.左旋转 3. 左右旋转 4. 右左旋转 三、基于二叉搜索树之平衡二叉树的代码实现 1.具体方法思路 2.java代码实现 一、平衡二叉树(AVL) 一种自平衡二叉搜索树,它是在每个节点上增加一个平衡因子…

Day 1 Vue 页面框架

现在前端框架越来越像后端了,特别是TypeScript这样的语言出现后,开发前端的体验跟后端渐渐接近了。当然,作为一个后端,直接上手前端,还是有很多坑要填的。 本次开发,前端页面框架直接选择Vue。原因很简单&…