10 generate执行plan

  • 最优的执行路径生成后,虽然 PathTree I已足够清楚指出查询计划要进行的物理操作,
    • 但它的结构体中为了进行代价计算有太多的冗余信息,不方便查询执行器使用,且有些参数还没有建立好,因此通过将其转换成执行计划来生成更适合查询执行器的 PlanTree,然后将
      PlanTree交给执行器就可以真正执行了。
  • 路径的结构体是Path或者是“继承”自Path的新
    的路径结构体,例如 Joinpath,对应的执行计划节点的结构体是Plan或者是“继承”自Plan的
    新的执行计划节点,例如Join结构体。
  • 每个Path节点都一一对应一个Plan节点,
    • 最优的执行路径需要通过 create plan函数转换成对应的执行计划

10.1 转换流程

10.1.1扫描计划

  • 生成扫描路径时,介绍3种:顺序扫描路径、索引扫描路径、位图
    扫描路径。
  • 这些路径节点(Path)都要转换成新的计划节点(Plan),
    • 在分别转换每个路径之前,所有的扫描节点有一些公共的事情要处理,于是通过 create_scan_plan先处理所有扫描路径转换过程中的公共部分。

  • 通常,扫描节点上只有过滤条件,
    • 可通过 Reloptlnfo->baserestrictinfo
      获得,但索引例外,IndexOptinfo中通过indrestrictinfo也保存一份过滤条件,indrestrictinfo通常和 baserestrictinfo相同,
    • 但对于带有谓词的局部索引,可能不同

10 generate执行plan

  • 如果扫描的上层是连接,那可能会有下推的参数化的约東条件,
    • 这些原本是连接型的过滤条件(连接型指操作符两端都是变量的过滤条件)或连接条件,
    • 由于操作符一端的变量可以参数化(可假设为常量),
    • 如果 join clause is movable_to函数判断其可以下推,
    • 那这个约束就可作为下层扫描节点的过滤条件,

10 generate执行plan

  • 普通的约束条件和参数化的约東条件组合在一起,
    • 就形成了这个扫描节点上所有的“扫描条件(scan_cluase)”

10.1.1.1顺序执行计划

  • 这时已经获得了扫描的约束条件和扫描产生的投影列,
  • 对于顺序扫描而言已万事俱备,只需对顺序扫描路径中的数据做些调整,就可以生成扫描执行计划。

  • 首先,调整约束条件的执行顺序,这里调整的规则涉及了安全级别和表达式的执行代价(本书不介绍安全级别相关的知识),安全级别相同情况下,以约束条件中的表达式代价
    作为排序的依据,表达式代价越低的约東条件排序越靠前。

  • 其次,査询优化中,所有约束条件都用Restrictlnfo表示,
    • 这个结构体作用是记录和约束条件相关的物理优化信息(例如等价类信息、代价信息等),这些信息在创建和筛选Path的过程中发挥作用,但到了生成执行计划的阶段,已变成冗余,查询执行器中只需要知道待执行的表达式就可以,因此还需从Restrictlnfo中将表达式提取出来,査询执行器只需要执行这些表达式就可

  • 如果当前扫描路径是参数化路径,那么需要检查约束条件中是否引用了外表的列作为参数,如果引用了外表的列(Var或Placeholdervar),那么把它们替换成Param,并且建立对应的NestloopParam结构体。
  • 目前的Pg在顺序扫描的约束条件中不会出现参数化路径,
    • 它的参数主要出现在投影列中,但投影列的参数替换是在 create_scan_plan->build_path_tlist中进行。