OpenGuass之分区裁剪

一. 前言

​       本文将假设以一个以id为分区字段的表t1, 以SQL: select * from t1 where id > 2 and id < 5 为例讲述在OpenGuass中是如何进行分区裁剪的。如下图所示,本来t1有个6分区,但是OpenGuass会根据 id > 2 and id < 5的谓词条件进行无交集的分区裁剪,裁剪后实际扫描数据的时候,只会访问3个分区。

二. OpenGuass 分区裁剪过程
partitionPruningForRestrictInfo
    partitionPruningForExpr
        partitionPruningWalker
            recordBoundaryFromOpExpr    // 将根据谓词条件确认需要访问分区的上下界
                // 下边的for循环将谓词条件逐个遍历,比如这里有id > 2 和id < 5
                    for(cell, expr->args)  {
                        partitionPruningWalker(arg, context);
                            recordBoundaryFromOpExpr
                            // 根据谓词条件决定上下界,比如>2 的条件下界为2, <5的条件上界为5
                            if(strcmp(">", opName)) {
                                boundary->min[attrOffset] = PointerGetDatum(constArg);
                            }
                            if (strcmp("<", opName) {
                                boundary->max[attrOffset] = PointerGetDatum(constMax);
                            }                                                 ......
                         resultList = lappend(resultList, iterator)    // 保存谓词条件与分区的交集
                     }
                     // 有了所有谓词条件的上下界后,将根据谓词连接是and 还是or 决定取交集还是并集
                     switch (expr->boolop) {
                         case AND_EXPR : intersectChildPruningResult   // 将所有的谓词条件去交集保存为最后的谓词结果
                         case OR_EXPR : unionChildPruningResult    // 取所有谓词条件的并集为最后的结果
                     }
             // 如下的partitionPruningFromBoundary将根据上边获取的谓词条件与分区键的值比较,决定该分区的取舍   
             partitionPruningFromBoundary
                  bottomValue =  pruningResult->boundary->min    // 谓词条件的上下界
                  topValue =   pruningResult->boundary->max 
                  partitionRoutingForValueRange(u_sess->opt_cxt.bottom_seq)  // 将谓词与分区键的较大值作为分区起始扫描值
				  getRangePartitionOid(keyValue) // 根据上下界的值找对应的分区oid
                  partitionRoutingForValueRange(u_sess->opt_cxt.top_seq)  // 将谓词条件与分区键的较小值作为分区结束扫描值
				  getRangePartitionOid(keyValue) // 根据上下界的值找对应的分区oid
             //  保存裁剪后需要扫描的分区
             for (i = rangeStart; i <= rangeEnd; i++) {
                    rangeBms = bms_add_member(rangeBms, i)
            }
           pruningResult->bm_rangeSelectedPartitions = rangeBms   // bm_rangeSelectedPartitions保存的是最后要扫描的分区的分区的列表。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值