Presto RBO之 InlineProjections和RemoveRedundantIdentityProjections

一. InlineProjections优化规则

1. 优化效果

InlineProjections 用来优化常量表达式的数据列,此优化规则会将常量表达式的数据列直接裁剪掉,引用到常量表达式数据列的输出改写成直接使用常量计算。这样可以减少数据列传输和计算。

如下图是个优化效果示例:

2. 实现原理

public Result apply(ProjectNode parent, Captures captures, Context context)
{
    ProjectNode child = captures.get(CHILD);

    // taget是需要优化掉的child Project的常量数据列,如上图的红框中的列
    Sets.SetView<Symbol> targets = extractInliningTargets(parent, child);
    if (targets.isEmpty()) {
        return Result.empty();
    }

    // inline the expressions
    Assignments assignments = child.getAssignments().filter(targets::contains);
    
    //parentAssignments为parent中引用到project source常量数据式的列,如上图的绿框中的列
    // 如下的作用是绿框的引用到常量列的输出换成常量
    Map<Symbol, Expression> parentAssignments = parent.getAssignments()
            .entrySet().stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> inlineReferences(entry.getValue(), assignments)));

    // Synthesize identity assignments for the inputs of expressions that were inlined
    // to place in the child projection.
    // If all assignments end up becoming identity assignments, they'll get pruned by
    // other rules
    Set<Symbol> inputs = child.getAssignments()
            .entrySet().stream()
            .filter(entry -> targets.contains(entry.getKey()))
            .map(Map.Entry::getValue)
            .flatMap(entry -> SymbolsExtractor.extractAll(entry).stream())
            .collect(toSet());

    //裁剪掉project source的常量数据列
    Assignments.Builder childAssignments = Assignments.builder();
    for (Map.Entry<Symbol, Expression> assignment : child.getAssignments().entrySet()) {
        if (!targets.contains(assignment.getKey())) {
            childAssignments.put(assignment);
        }
    }
    for (Symbol input : inputs) {
        childAssignments.putIdentity(input);
    }

    return Result.ofPlanNode(
            new ProjectNode(
                    parent.getId(),
                    new ProjectNode(
                            child.getId(),
                            child.getSource(),
                            childAssignments.build()),
                    Assignments.copyOf(parentAssignments)));
}

二. RemoveRedundantIdentityProjections优化规则

   1. 优化效果

   RemoveRedundantIdentityProjections较为简单,用于去除输入和输出是一模一样的算子。

   2. 实现原理

private static boolean outputsSameAsSource(ProjectNode node)
{
    return ImmutableSet.copyOf(node.getOutputSymbols()).equals(ImmutableSet.copyOf(node.getSource().getOutputSymbols()));
}

@Override
public Pattern<ProjectNode> getPattern()
{
    return PATTERN;
}

@Override
public Result apply(ProjectNode project, Captures captures, Context context)
{
    //上边的outputsSameAsSource判断此算子的输出和source的输出是否是一模一样的,如果是一模一样的话,此算子是毫无作用的,直接用此算子的Source的输入替换此算子的输出即可
    return Result.ofPlanNode(project.getSource());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值