四川省网站建设广告设计与制作工作内容
web/
2025/9/26 3:22:40/
文章来源:
四川省网站建设,广告设计与制作工作内容,扬中网站,宁波企业黄页公司黄页PgSQL技术内幕-Bitmap Index Scan 1、简介 Bitmap索引扫描是对索引扫描的一个优化#xff0c;通过建立位图的方式将原来的随机堆表访问转换成顺序堆表访问。主要分为两点#xff1a;1#xff09;管理每个Bitmap的hash slot没用完时#xff0c;每个Bitmap代表每个heap页中满… 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结构主要成员如下图所示 各个成员变量的说明 1每一页的bitmap由PagetableEntry结构来管理里面成员主要有blockno页号用做hash表的key。最初仅使用entry1entry1满了才会使用hash表。这样btgetbitmap扫描完成所有存在的TID就完成了按照页聚合。 2pagetable哈希表初始时tbm_create调用时指定仅创建128个hash桶。若一个page对应一个PagetableEntry当有大量page需要构建bitmap时就不够用了。所以Hash桶用完则转换chunk进行lossy从而腾出空闲槽。等hash桶都变成chunk时就需要扩展了每次扩展2倍大小2*128。 3nentries表示hash表中已使用桶的个数 4maxentries为hash表hash桶的最大个数限制。该成员主要作用控制何时进行lossy也就是nentries maxentries时需要tbm_lossify。大小由work_mem控制至少16个。当然如果最终扩展的超过work_mem时桶仍旧都是chunk则更新maxentries扩展2倍大小。 5entriy1表示最开始使用的entry不用申请到hash表 6spages和schunks则是从hash桶弄过来排过序的entry。在BitmapHeapScan阶段使用。当然分别存储Page和lossy的chunk。这样就可以顺序访问了。 另外TIDBitmap中的几个成员有 1TBMStatus 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索引扫描函数 btgetbitmap函数的逻辑当然时先创建TIDBitmap然后调用_bt_first/_bt_next逐条获取满足条件的item接着通过tbm_add_tuples将其添加到TIDBitmap中最终构建一个完整的bitmap核心函数为_bt_first/_bt_next/tbm_add_tuples 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重复以上过程直至扫描结束。 3tbm_create创建TIDBitmap 4tbm_add_tuples函数添加CTID构建TIDBitmap tbm_add_tuples要干的事如上图所示 1btgetbitmap调用tbm_add_tuples每次仅添加一个TID从TID中解析出对应heap tuple的页号blk及页内偏移off 2判断blk是否是lossy页号定位到所属chunk;然后据该chunk页号从hash表中查找hash表中找到再看下页号所属的bitmap位是否1即是否lossybitmap为1则返回true blk非lossy则调用tbm_get_pageentry从hash表中找一个PagetableEntry不存在则会创建。但是若此时只有一个PagetableEntryTBM_ONE_PAGE状态则直接返回entry1不需要从hash查找 blk是lossy:已经位于chunk中的一位了不必再向hash表添加了因为btree下仅一个TID所以退出循环 3计算bitmap的位于哪个字节wordnum及哪一位bitnum标记到PagetableEntry的bitmap中words并设置recheck为false 4tbm_get_pageentry创建了一个新PagetableEntry发现npages超过tbm-maxentries只则会调用tbm_lossify函数将TIDBitmap中部分PagetableEntry转成成lossy chunk同时按照exact page的减少和lossy page的增加相应修改npages和nchunks tbm_lossify函数 那么hash表何时扩展呢只要向hash表插入PagetableEntry就有可能涉及到扩展扩展后maxentries并不是立即更新pagetable_insert调用结束后若插入则需要更新nentries 当然还会有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: BitmapHeapNext的核心逻辑如下 1从下层节点拿到TIDBitmap结果tbm 2tbm_generic_begin_iterate-tbm_begin_iterate基于tbm构建一个iterator:从hash表中取出PagetableEntry根据它是exact page还是lossy page分别放到spages[]和schunks[]数组然后根据页号进行排序 3先调用tbm_iterate从spages[]和schunks[]数组拿一个较小页号的页然后通过table_scan_bitmap_next_block-heapam_scan_bitmap_next_block读取一个page到ScanDesc的rs_buffer里。 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/web/81979.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!