当前位置: 首页> 科技> 能源 > opeGauss 之BitmapOr算子代码走读

opeGauss 之BitmapOr算子代码走读

时间:2025/7/11 18:12:24来源:https://blog.csdn.net/wangfeihuo/article/details/142266975 浏览次数:0次
一. 前言

        在openGauss中,BitmapOr算子扫描是指谓词条件是索引列的or条件时,将多个or条件的索引谓词先组成一个需要扫描元组的BitmapOr扫描算子,然后再通过BitmapOr算子的tid信息去扫描元组,从而减少or条件带来的随机扫描过多的问题,如下所示:

      本文主要通过走读代码了解openGauss是怎么实现BitmapOr算子的功能的。

二. 执行计划生成

       执行计划生成主要是如何在堆扫描下生成一个BitmapOr算子,BitmapOr算子包含所要扫描的元组信息。执行计划生成的入口在create_index_paths函数中,主要的代码流程如下所示:

create_index_pathsindexpaths = generate_bitmap_or_paths(root, rel, rel->baserestrictinfo, NIL, false);foreach (lc, clauses) {if (!restriction_is_or_clause(rinfo))     // 只支持or语句continue;foreach (j, ((BoolExpr*)rinfo->orclause)->args) {  // 遍历各个or条件build_paths_for_ORmatch_clauses_to_index(index, clauses, &clauseset);   // 检查索引和谓词的匹配情况indexpaths = build_index_paths   // 每个or条件只是建立一个普通索引result = list_concat(result, indexpaths);  // 把当前的索引建出来的路径保存到结果中bitmapqual = choose_bitmap_and(root, rel, indlist, globalIndexList); // 合并多索引情况下的bitmap和挑选代价最小的索引for (i = 0; i < npaths; i++) {if (i == 0 || chooseInfo.costsofar < bestcost) {bestpaths = chooseInfo.paths;bestcost = chooseInfo.costsofar;}}pathlist = lappend(pathlist, bitmapqual);}bitmapqual = (Path*)create_bitmap_or_path(root, rel, pathlist);  // 所有约束参数的索引连起来形成bitmap索引cost_bitmap_or_node(pathnode, root);foreach (l, path->bitmapquals) {cost_bitmap_tree_node(subpath, &subCost, &subselec);selec += subselec;   // bitmap or的代价为各个or索引的代价之和}   }indexpaths = generate_bitmap_or_paths(root, rel, joinorclauses, rel->baserestrictinfo, false); // 如果有or条件的话,也利用or条件作为约束生成一个新的bitmap pathbitmapqual = choose_bitmap_and(root, rel, bitindexpaths); // 如果有多个bitmap索引路径生成,挑选出代价最小的bpath = create_bitmap_heap_path(bitmapqual);  //生成最后的堆扫描路径,bitmapqual条件为上述生成的bitmapor路径add_path(root, rel, (Path*)bpath);   // 保存路径

三. 算子层的实现

     算子层的实现入口在BitmapHeapTblNext函数中,代码流程如下所示:

BitmapHeapTblNextif (tbm == NULL) {    初始化需要扫描元组tid的bitmapMultiExecProcNode(outerPlanState(node));  // 获取需要访问的元组的tid,并且生成bitmapMultiExecBitmapIndexScan  scan_handler_idx_getbitmap(scandesc, tbm)index_getbitmap(scan, bitmap)btgetbitmap_internal(IndexScanDesc scan, TIDBitmap *tbm)for (;;) {    // 根据谓词条件确认访问元组的上下界,并且将对应的位置加入到bitmap中tbm_handler._add_tuples(tbm, heapTid, 1, false, currPartOid, bucketid); // 把索引的元组位置转成bitmap}TableScanBitmapNextBlock(scan, tbmres, &node->ss.ps.state->have_current_xact_date)heapam_scan_bitmap_next_blockhscan->rs_base.rs_cbuf = ReleaseAndReadBuffer();   // 拿到bufffor (curslot = 0; curslot < tbmres->ntuples; curslot++) {OffsetNumber offnum = tbmres->offsets[curslot];hscan->rs_base.rs_vistuples[ntup++] = ItemPointerGetOffsetNumber  // 获取位置信息}}TableScanBitmapNextTupleHeapamScanBitmapNextTupletargoffset = hscan->rs_base.rs_vistuples[hscan->rs_base.rs_cindex];lp = PageGetItemId(dp, targoffset);   // 获取到元组所在的位置hscan->rs_ctup.t_data = (HeapTupleHeader)PageGetItem((Page)dp, lp);  // 拿到数据hscan->rs_base.rs_cindex++;   // ++ 指向下一次读取的位置

关键字:opeGauss 之BitmapOr算子代码走读

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: