openGauss 之min/max 优化代码走读

一. 前言

       在openGuass中,如果对索引列执行max/min操作,openGauss会优化成只读取索引的最前/后的一行数据,避免了对整表数据进行读取和聚合操作,如下所示:

二. min/max优化代码走读

      1. 首先需要将min/max 算子转成成执行计划中降序/升序的keypath,代码流程如下所示:

preprocess_minmax_aggregates
  find_minmax_aggs_walker // 从pg_aggregate中查出max/min对应的aggsortop,max对应的是>, min对应的是<
    get_equality_op_for_ordering_op //根据aggsortop到pg_amop表中查找对应的op信息,如amopstrategy等,对应是查询中是需要顺序扫描还是逆序扫描
      build_minmax_path
         sortcl->eqop = eqop;
         sortcl->sortop = sortop
         parse->sortClause = st_make1(sortcl);  // 已经将max/min聚合操作映射成排序操作,max对应的是逆序,min对应着是顺序
         parse->limitCount = makeConst(1)  // 其实已经将执行计划中的max替换成了order by desc limit 1,min被替换成了 order by asc limit 1
         query_planner
           construct_pathkeys
             construct_pathkeys
                make_pathkeys_for_sortclauses
                   make_pathkey_from_sortop  // 根据第一步拿到的aggsortop生成pathkey
                      make_pathkey_from_sortinfo
                        strategy = reverse_sort ? BTGreaterStrategyNumber : BTLessStrategyNumber
                        makePathKey(strategy)  在执行计划中将min/max映射成的keypath信息保存下来

      2. 生成索引路径的时候,根据keypath的信息生成顺序扫描路径还是逆序扫描路径,主要代码如下所示:

build_index_paths
    if(useful_pathkeys != NIL) {
        ipath = create_index_path(index_is_ordered ? ForwardScanDirection : NoMovementScanDirection) // 首先生成正向的扫描路径
    }
    index_pathkeys = build_index_pathkeys  
    useful_pathkeys = truncate_useless_pathkeys // 将索引的keypath和查询中的keypath做交集,如果有交集,则再生成逆序的扫描路径
    if(useful_pathkeys != NIL) {
        ipath = create_index_path(BackwardScanDirection) // 建立反向扫描的index     
    }

     3.  add_path的时候将带有pathkey的路径保存下来,主要代码流程如下所示:

add_path
   costcmp = compare_path_costs_fuzzily
   keyscmp = compare_pathkeys
      // 如下通过case判断如果执行计划或者keypath 有一个占优势的执行路径都会被保留

三.  min/max 的区别

      min/max算子均走上述流程,其差异主要为当是min算子时候,build_index_paths中truncate_useless_pathkeys裁剪后的keypath为空,导致不会生成逆序扫描的执行计划。主要代码如下所示:

truncate_useless_pathkeys
    pathkeys_useful_for_ordering
       pathkeys_contained_in
           compare_pathkeys
               if (pathkey1->pk_strategy != pathkey2->pk_strategy) {  // 因为索引的顺序是升序的,但是min算子对应的operator算子是降序的,因此才减掉此keypath,但是对于max算子,顺序是一致的,因此会保留此keypath
                   return PATHKEYS_DIFFERENT
               }
if (nuseful == 0)
     return NIL;   // 返回空空将不会创建反序列的路径

相关推荐

  1. openGauss 鲲鹏NUMA架构优化

    2024-04-14 05:56:03       30 阅读
  2. 优化代码分支

    2024-04-14 05:56:03       46 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-14 05:56:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-14 05:56:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-14 05:56:03       82 阅读
  4. Python语言-面向对象

    2024-04-14 05:56:03       91 阅读

热门阅读

  1. OneFlow深度学习框架介绍

    2024-04-14 05:56:03       36 阅读
  2. 【磁盘清理】/var/lib/docker/overlay2 占用空间过大

    2024-04-14 05:56:03       33 阅读
  3. 新能源汽车动力电池散热技术

    2024-04-14 05:56:03       33 阅读
  4. Node.js 常用命令

    2024-04-14 05:56:03       38 阅读
  5. Vue Router 路由动态缓存组件

    2024-04-14 05:56:03       37 阅读