// Optimize does optimization and creates a Plan. // The node must be prepared first. func Optimize(ctx context.Context, node ast.Node) (plan.Plan, error) { // We have to infer type again because after parameter is set, the expression type may change. if err := InferType(node); err != nil { return nil, errors.Trace(err) } if err := logicOptimize(ctx, node); err != nil { return nil, errors.Trace(err) } p, err := plan.BuildPlan(node) if err != nil { return nil, errors.Trace(err) } alts, err := plan.Alternatives(p) if err != nil { return nil, errors.Trace(err) } err = plan.Refine(p) if err != nil { return nil, errors.Trace(err) } bestCost := plan.EstimateCost(p) bestPlan := p for _, alt := range alts { err = plan.Refine(alt) if err != nil { return nil, errors.Trace(err) } cost := plan.EstimateCost(alt) if cost < bestCost { bestCost = cost bestPlan = alt } } return bestPlan, nil }
// Optimize does optimization and creates a Plan. // The node must be prepared first. func Optimize(ctx context.Context, node ast.Node, sb plan.SubQueryBuilder) (plan.Plan, error) { // We have to infer type again because after parameter is set, the expression type may change. if err := InferType(node); err != nil { return nil, errors.Trace(err) } if err := logicOptimize(ctx, node); err != nil { return nil, errors.Trace(err) } p, err := plan.BuildPlan(node, sb) if err != nil { return nil, errors.Trace(err) } err = plan.Refine(p) if err != nil { return nil, errors.Trace(err) } return p, nil }