Presto - Coordinator 查询流程-5(逻辑计划优化)

497 阅读1分钟

上接:Presto - Coordinator 查询流程-4,上章讲到逻辑计划的构建,生成了PlanNode root,逻辑计划,本章将继续讲解逻辑计划的优化;

1. 逻辑计划 Plan

逻辑计划优化代码入口在LogicalPlanner#plan方法中的如下代码片段;

for (PlanOptimizer optimizer : planOptimizers) { // 优化
    root = optimizer.optimize(root, session, symbolAllocator.getTypes(), symbolAllocator, idAllocator, warningCollector);
    requireNonNull(root, format("%s returned a null plan", optimizer.getClass().getName()));
}

2. Optimizer

优化是通过Optimizers实现的,每一个Optimizer都通过vistor模式修改逻辑计划树,在不修改查询意图的基础上,加速查询;Presto实现的Optimizer比较少,只有最基本如LimitPushDown, IndexJoinOpitimizer;如果有意向深入的了解优化器,可以查看Spark的优化器;在Presto中有一个AddExchange优化器比较特殊,给逻辑计划树添加Exchange节点,标志这个地方需要执行数据交换,后续会根据Exchange节点切分逻辑计划,生成分布式的逻辑计划;

2.1 优化器的功能

  • 常量折叠
  • 算子(条件,选择)下推
  • 算子重写,比如Distinct重写成groupby语句
  • 算子结合,Union结合,Project结合,Filter结合等
  • 代码生成,比如大量case when会生成代码
  • 子查询递归优化
  • 文件数据源的下推,比如pruneFileSourcePartitions

2.1 AddExchange

AddExchange是Presto中体比较特殊优化器,用于后续切分逻辑计划, 可能添加Exchange的地方包括, Aggregate节点,Join节点,Distinct节点,Window节点等;添加Exchange逻辑不相同,可以理解为需要shuffle的地方都会添加ExchangeNode;