PgSQL技术内幕-Bitmap Index Scan

PgSQL技术内幕-Bitmap Index Scan

1、简介

Bitmap索引扫描是对索引扫描的一个优化,通过建立位图的方式将原来的随机堆表访问转换成顺序堆表访问。主要分为两点:1)管理每个Bitmap的hash slot没用完时,每个Bitmap代表每个heap页中满足条件元组的ItemIDs,通过Bitmap扫描heap页时需要将所有Bitmap按照页号进行排序,然后依次获取heap页中记录,依次完成顺序回表。2)当hash slot用完时,就需要将heap页的bitmap范围扩大,转换成一个chunk的bitmap,也就是Bitmap中一位代表页内具有满足条件元组的页。此时,整个Bitmaps有chunk的bitmap也有页的bitmap,该chunk的页号为chunk内最小页号,所以Bitmaps排序后,整体上也是有序的。如此完成顺序扫描heap页,只不过对于Chunk的bitmap中一位代表的heap 页需要再次进行条件检测,将满足条件的tuple输出。

2、Bitmap Index Scan中的Bitmap是什么

Bitmap index scan先利用索引获取满足条件的Tid,将其保存到TIDBitmap中。由TIDBitmap管理满足条件的heap tuple的Bitmap。TIDBitmap结构主要成员如下图所示:

c08016319958a4b8485e1f80ad585259.png

各个成员变量的说明:

1)每一页的bitmap由PagetableEntry结构来管理,里面成员主要有blockno:页号,用做hash表的key。最初仅使用entry1,entry1满了,才会使用hash表。这样btgetbitmap扫描完成所有存在的TID,就完成了按照页聚合。

2)pagetable哈希表,初始时(tbm_create调用时指定)仅创建128个hash桶。若一个page对应一个PagetableEntry,当有大量page需要构建bitmap时,就不够用了。所以Hash桶用完则转换chunk进行lossy,从而腾出空闲槽。等hash桶都变成chunk时,就需要扩展了,每次扩展2倍大小(2*128)。

3)nentries表示hash表中已使用桶的个数

4)maxentries为hash表hash桶的最大个数限制。该成员主要作用:控制何时进行lossy,也就是nentries > maxentries时,需要tbm_lossify。大小由work_mem控制,至少16个。当然,如果最终扩展的超过work_mem时,桶仍旧都是chunk,则更新maxentries扩展2倍大小。

5)entriy1表示最开始使用的entry,不用申请到hash表

6)spages和schunks则是从hash桶弄过来排过序的entry。在BitmapHeapScan阶段使用。当然,分别存储Page和lossy的chunk。这样就可以顺序访问了。

另外TIDBitmap中的几个成员有:

1)TBMStatus status:

typedef enum
{TBM_EMPTY, /* no hashtable, nentries == 0 */TBM_ONE_PAGE, /* entry1 contains the single entry */TBM_HASH /* pagetable is valid, entry1 is not */
} TBMStatus;

为什么会有TBM_ONE_PAGE和TBM_HASH呢?因为如果TIDBitmap只存储一个PagetableEntry,不需要耗费实际构建动态hash表,查找时也不需要通过hash查找,只需要使用entry1即可。

3、Bitmap Index Scan阶段

MultiExecBitmapIndexScan函数实现了Exec逻辑,主要通过调用index_getbitmap函数,获取bitmap,然后将bitmap返回给上一层算子。我们这里以btree索引为例,所以index_getbitmap指向btgetbitmap索引扫描函数:

7f34eddaec40c760726f99bef1716bba.png

btgetbitmap函数的逻辑:当然时先创建TIDBitmap,然后调用_bt_first/_bt_next逐条获取满足条件的item,接着通过tbm_add_tuples将其添加到TIDBitmap中,最终构建一个完整的bitmap,核心函数为_bt_first/_bt_next/tbm_add_tuples:

0291ffd509c9d55f8e8ef068b99d3388.png

1)_bt_first函数时索引扫描的开始。首先调用_bt_preprocess_keys预处理扫描key,所扫描key条件无法满足,则设置BTScanOpaque->qual_ok为false,提前结束扫描。若没有找到有用的边界keys,需要调用_bt_endpoint从第一页开始,否则调用_bt_search从btree的root节点_bt_getroot开始扫描,直到找到符合扫描key和快照的第一个叶子节点。之后使用二分查找_bt_binsrch找到符合扫描key的页内item偏移,最好将找到的页面载入buffer并返回tuple。

2)_bt_next函数从当前页获取下一条tuple,若当前页没有tuple,则调用_bt_steppage拿到下一页页号,之后调用_bt_readnextpage读取文件块中的内容,然后_bt_next获取吓一跳tuple,重复以上过程,直至扫描结束。

3)tbm_create创建TIDBitmap:

eeeb1e996b6e4766faf472c5299c6010.png

4)tbm_add_tuples函数添加CTID,构建TIDBitmap

837d2f9ed80b6ef265a63c4b76b06c99.png

tbm_add_tuples要干的事如上图所示:

(1)btgetbitmap调用tbm_add_tuples每次仅添加一个TID,从TID中解析出对应heap tuple的页号blk及页内偏移off

(2)判断blk是否是lossy:页号定位到所属chunk;然后据该chunk页号从hash表中查找;hash表中找到,再看下页号所属的bitmap位是否1,即是否lossy;bitmap为1,则返回true:

a31c88e749272f9f4756d306abfff515.png

blk非lossy,则调用tbm_get_pageentry从hash表中找一个PagetableEntry(不存在则会创建)。但是若此时只有一个PagetableEntry(TBM_ONE_PAGE状态)则直接返回entry1,不需要从hash查找:

b06e45eb9630b5b883058630889187e2.png

blk是lossy:已经位于chunk中的一位了,不必再向hash表添加了,因为btree下仅一个TID,所以退出循环

(3)计算bitmap的位于哪个字节wordnum及哪一位bitnum,标记到PagetableEntry的bitmap中words,并设置recheck为false

(4)tbm_get_pageentry创建了一个新PagetableEntry,发现npages超过tbm->maxentries只,则会调用tbm_lossify函数,将TIDBitmap中部分PagetableEntry转成成lossy chunk,同时按照exact page的减少和lossy page的增加,相应修改npages和nchunks

tbm_lossify函数

8a7ec42e8fc7794fbf990a791edf2ab9.png

那么hash表何时扩展呢?只要向hash表插入PagetableEntry,就有可能涉及到扩展,扩展后maxentries并不是立即更新;pagetable_insert调用结束后,若插入则需要更新nentries

de1d2939506a64ff34fdd3db9407c222.png

当然,还会有Bitmap And和Bitmap Or的情况。BitmapAnd节点对两个Bitmap进行与操作,生成交集位图;BitmapOr节点对两个Bitmap进行或操作,生成并集位图。

至此,bitmap index scan阶段完成bitmap的构建,下一步就是根据TID bitmap来扫描heap,返回符合条件的tuple,即Bitmap Heap Scan。

4、Bitmap Heap Scan阶段

Bitmap Heap Scan使用Bitmap Index Scan阶段生成的bitmap来查找相关数据。位图的每个页可以是精确的(直接指向heap页的tuple),也可以是有损的(指向包含至少一行与查询匹配的页)。算子由ExecBitmapHeapScan函数执行,主要实现函数为BitmapHeapNext:

c128cb415214e9767e8dd248449d69ac.png

BitmapHeapNext的核心逻辑如下:

4b2da4979f78377cebef69e0aecd8b34.png

1)从下层节点拿到TIDBitmap结果tbm

2)tbm_generic_begin_iterate->tbm_begin_iterate基于tbm构建一个iterator:从hash表中取出PagetableEntry,根据它是exact page还是lossy page,分别放到spages[]和schunks[]数组;然后根据页号进行排序

cfc344a30120f2ee5be3ba2f826b183d.png

3)先调用tbm_iterate从spages[]和schunks[]数组拿一个较小页号的页,然后通过table_scan_bitmap_next_block->heapam_scan_bitmap_next_block读取一个page到ScanDesc的rs_buffer里。

cd18133056957e18cefc68fbcb0a1bf6.png

4)调用table_scan_bitmap_next_tuple->heapam_scan_bitmap_next_tuple根据TBMIterateResult里的偏移,再内存buffer里获取相应的tuple。当这一页扫描完,则重置node->tbmres = tbmres = NULL,重新获取下一个PagetableEntry的bitmap继续循环。

5)如果是lossy,则还需要继续过滤

5、总结

Bitmap索引扫描分为两个阶段,第一阶段通过索引进行扫描,将满足条件的元组TID构建到bitmap中,一般情况一个页一个bitmap;第二阶段将bitmap按照页号进行排序,按次序从页的bitmap中取出heap tuple的TID,从而达到索引顺序扫描heap的目的。

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

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

相关文章

在VS Code中查看Word, PDF, Excel

文章目录 vscode-pdfExcel Vieweroffice viewerVS Code神级插件 vscode-pdf 这年头连Edge浏览器都支持pdf阅读,那么VS Code不支持显然不太合适。搜索并安装vscode-pdf之后,就可以非常便捷地查看pdf文档了。vscode-pdf是基于pdf.js开发的阅读插件&#x…

计算机毕业设计python企业员工人事管理系统vue

管理员: 1.员工资料管理:查看员工列表,添加职工,修改信息(搜索员工使用模糊查询) 2.部门管理:查看部门列表,修改信息,添加新部门 3.职工考勤管理:添加&#x…

BUUCTF [BJDCTF2020]鸡你太美 1

BUUCTF:https://buuoj.cn/challenges 题目描述: 得到的 flag 请包上 flag{} 提交。来源: https://github.com/BjdsecCA/BJDCTF2020 密文: 下载附件,解压得到两个.gif图片。 第一个gif图片: 第二个gif图片无法打开。…

XCTF(攻防世界)---Web新手区题目WP

unseping&#xff0c;unserialize3&#xff0c;php_unserialize: 知识点&#xff1a; PHP序列化与反序列化 基本知识&#xff1a; <?php $b array(hello, world, !!!); $b serialize($a); echo($b.PHP_EOL); ?>输出&#xff1a; a:3:{i:0;s:5:"hello";i:…

vue3-响应式核心

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-响应式核心 响应式核心 目录 响应式核心 3.1ref() 3.2computed () 3.3 reactive() 3.4 …

【代码随想录】算法训练计划27

回溯 1、39. 组合总和 题目&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的…

【Java】多线程-wait/notify

1、wait和notify Java的多线程中&#xff0c;线程的执行顺序和时间都是不定的。为了控制线程的调度顺序&#xff0c;前面我们引入了join()方法。 但是join()只能在线程执行完后&#xff0c;才能执行其他线程&#xff0c;有没有什么方法可以在线程执行顺序中来调度其他线程呢&…

CTF-PWN-小tips

文章目录 overflowscanfgetreadstrcpystrcat Find string in gdbgdbgdb peda Binary ServiceFind specific function offset in libc手工自动 Find /bin/sh or sh in library手动自动 Leak stack addressFork problem in gdbSecret of a mysterious section - .tlsPredictable …

【腾讯云 HAI域探秘】高性能服务器引领AI革新浪潮:从AI绘画、知识问答到PyTorch图像分类、视频检测的全方位探索

目录 1 HAI&#xff08;高性能应用服务&#xff09;简介2 HAI的应用场景2.1 HAI在AI作画中的灵活性与效率2.2 深入探索LLM语言模型的应用与性能2.3 HAI支持的AI模型开发环境与工具 3 基于stable difussio的AI 绘画应用实践3.1 使用AI模型中的stable diffusion模型服务3.2 设置和…

10个好用的Mac数据恢复软件推荐—恢复率高达99%

如果您正在寻找最好的 Mac 数据恢复软件来检索意外删除或丢失的文件&#xff0c;那么这里就是您的最佳选择。 我们理解&#xff0c;当您找不到 Mac 计算机或外部驱动器上保存的一些重要文件时&#xff0c;会感到多么沮丧和绝望。这些文件非常珍贵&#xff0c;无论出于何种原因…

【寒武纪(14)】硬件系统由标量指令、向量指令、张量指令、访存指令构成

我们在文档《Cambricon-BANG-C-Developer-Guide-EN-v4.5.1》的build-in function 发现&#xff0c;存在三种计算&#xff1a;矩阵乘法、标量类型、向量。 查阅《Cambricon-BANG-C-CProgramming-Guide-CN-v1.5.0.pdf》可知&#xff0c;硬件系统由标量指令、向量指令、张量指令、…

vscode设置前进、后退快捷键

前言 在我们使用vscode编写程序时&#xff0c;经常需要在不同的文件之间跳来跳去&#xff0c;如果只是依靠个人记忆去操作会显得非常不方便。本文介绍如何设置vscode的前进、后退快捷键。 1 vscode设置前进、后退快捷键 点击“设置”图标&#xff0c;然后点击“键盘快捷方式…

各类软件docker安装

docker Docker 要求 CentOS 系统的内核版本高于 3.10 &#xff0c;通过 uname -r 命令查看你当前的内核版本&#xff1a; uname -r 3.10.0-1062.1.2.el7.x86_64 安装 Docker&#xff1a; 安装 Docker&#xff1a;yum -y install dockerkafka和zookeeper docker pull wurstmei…

python刷题笔记1(42例题)

1. split()函数 str.split([sep [, maxsplit]]) 分割字符串&#xff0c;返回一个数组 2. 判断子串 # 判断子串是否在主串里面&#xff0c;是则输出“Yes”&#xff0c;否则输出“No” str1 input("子串&#xff1a;") str2 input("主串:") if str1 in s…

通信原理板块——差错控制编码或纠错编码

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、背景 数字信号在传输过程中&…

【寒武纪(13)】BANGC 报错 stack smashing detected

报错&#xff1a; *** stack smashing detected ***: <unknown> terminated *** stack smashing detected ***: <unknown> terminated CMake Error at mluop_generated_fault_kernel.mlu.o.cmake:221 (message):Error generating file/mnt/data/ef2301-sdk-0.10.0…

什么是策划能力?如何提高策划能力?

什么是策划能力&#xff1f; 通常我们理解的策划能力&#xff0c;大多指的是策划活动&#xff0c;比如举办一次活动先要进行活动策划&#xff0c;形成具体的行动方案&#xff0c;然后开展组织人力物力等资源&#xff0c;最终落地实施。策划能力包含活动策划&#xff0c;但又不…

vscode设置代码模板

一键生成vue3模板代码 效果演示 输入vue3 显示快捷键 按回车键 一键生成自定义模板 实现方法 进入用户代码片段设置 选择片段语言 vue.json输入自定义的代码片段 prefix是触发的内容&#xff0c;按自己的喜好来就行&#xff1b; body是模板代码&#xff0c;写入自己需要的…