diff --git a/plan/physical_plan_builder.go b/plan/physical_plan_builder.go index d96e451ea6..fa383ff4fb 100644 --- a/plan/physical_plan_builder.go +++ b/plan/physical_plan_builder.go @@ -31,7 +31,7 @@ const ( selectionFactor = 0.8 distinctFactor = 0.7 cpuFactor = 0.9 - aggFactor = 0.2 + aggFactor = 0.1 joinFactor = 0.3 ) @@ -359,7 +359,7 @@ func enforceProperty(prop *requiredProperty, info *physicalPlanInfo) *physicalPl if prop.limit != nil { count = prop.limit.Offset + prop.limit.Count } - info.cost += float64(info.count)*cpuFactor + float64(count)*memoryFactor + info.cost += sortCost(count) } else if prop.limit != nil { limit := prop.limit.Copy() limit.SetSchema(info.p.GetSchema()) @@ -371,6 +371,10 @@ func enforceProperty(prop *requiredProperty, info *physicalPlanInfo) *physicalPl return info } +func sortCost(cnt uint64) float64 { + return float64(cnt)*math.Log2(float64(cnt))*cpuFactor + memoryFactor*float64(cnt) +} + // removeLimit removes the limit from prop. func removeLimit(prop *requiredProperty) *requiredProperty { ret := &requiredProperty{ @@ -948,8 +952,7 @@ func (p *Sort) convert2PhysicalPlan(prop *requiredProperty) (*physicalPlanInfo, if err != nil { return nil, errors.Trace(err) } - cnt := float64(unSortedPlanInfo.count) - sortCost := cnt*math.Log2(cnt)*cpuFactor + memoryFactor*cnt + sortCost := sortCost(unSortedPlanInfo.count) if len(selfProp.props) == 0 { np := p.Copy().(*Sort) np.ExecLimit = prop.limit diff --git a/plan/plan_test.go b/plan/plan_test.go index 288b011ea8..7062e7c11c 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -922,6 +922,10 @@ func (s *testPlanSuite) TestCBO(c *C) { sql: "select count(*) from t t1 having 1 = 0", best: "Dummy->HashAgg->Selection", }, + { + sql: "select sum(a.b), sum(b.b) from t a join t b on a.c = b.c group by a.d order by a.d", + best: "LeftHashJoin{Table(t)->Table(t)}(a.c,b.c)->HashAgg->Sort->Trim", + }, { sql: "select count(*) from t group by c", best: "Index(t.c_d_e)[[,+inf]]->StreamAgg",