From 441e0fe932a217ca9b7266374da8763547ca2f30 Mon Sep 17 00:00:00 2001 From: Jian Zhang Date: Mon, 9 Jul 2018 16:47:57 +0800 Subject: [PATCH 1/2] plan: always chose the smaller child as outer for IndexJoin --- plan/exhaust_physical_plans.go | 35 ++++++++++++++++++++-------------- plan/plan.go | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/plan/exhaust_physical_plans.go b/plan/exhaust_physical_plans.go index 93e26d1f09132..2c6b229925fd9 100644 --- a/plan/exhaust_physical_plans.go +++ b/plan/exhaust_physical_plans.go @@ -519,22 +519,29 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *requiredProp) ([]PhysicalPlan, boo plans = append(plans, join...) } case InnerJoin: - join := p.getIndexJoinByOuterIdx(prop, 0) - if join != nil { - // If the plan is not nil and matches the hint, return it directly. - if leftOuter { - return join, true - } - plans = append(plans, join...) + lhsCardinality := p.Children()[0].cardinality() + rhsCardinality := p.Children()[1].cardinality() + + leftJoins := p.getIndexJoinByOuterIdx(prop, 0) + if leftOuter && leftJoins != nil { + return leftJoins, true } - join = p.getIndexJoinByOuterIdx(prop, 1) - if join != nil { - // If the plan is not nil and matches the hint, return it directly. - if rightOuter { - return join, true - } - plans = append(plans, join...) + + rightJoins := p.getIndexJoinByOuterIdx(prop, 1) + if rightOuter && rightJoins != nil { + return rightJoins, true } + + if leftJoins != nil && lhsCardinality < rhsCardinality { + return leftJoins, leftOuter + } + + if rightJoins != nil && rhsCardinality < lhsCardinality { + return rightJoins, rightOuter + } + + plans = append(plans, leftJoins...) + plans = append(plans, rightJoins...) } return plans, false } diff --git a/plan/plan.go b/plan/plan.go index e4151f0f7f72b..47bf36f35be0a 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -184,6 +184,8 @@ type LogicalPlan interface { // deriveStats derives statistic info between plans. deriveStats() (*statsInfo, error) + cardinality() float64 + // preparePossibleProperties is only used for join and aggregation. Like group by a,b,c, all permutation of (a,b,c) is // valid, but the ordered indices in leaf plan is limited. So we can get all possible order properties by a pre-walking. // Please make sure that children's method is called though we may not need its return value, @@ -324,6 +326,20 @@ func (p *baseLogicalPlan) extractCorrelatedCols() []*expression.CorrelatedColumn return corCols } +func (p *DataSource) cardinality() float64 { + if p.statsAfterSelect == nil { + return math.MaxFloat64 + } + return p.statsAfterSelect.count +} + +func (p *baseLogicalPlan) cardinality() float64 { + if p.stats == nil { + return math.MaxFloat64 + } + return p.stats.count +} + // PruneColumns implements LogicalPlan interface. func (p *baseLogicalPlan) PruneColumns(parentUsedCols []*expression.Column) { if len(p.children) == 0 { From 041929e2de8ccaebb551c030399326678b985227 Mon Sep 17 00:00:00 2001 From: Jian Zhang Date: Mon, 30 Jul 2018 20:47:47 +0800 Subject: [PATCH 2/2] address comment --- plan/exhaust_physical_plans.go | 4 ++-- plan/plan.go | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/plan/exhaust_physical_plans.go b/plan/exhaust_physical_plans.go index 3c7230a6951b9..906bb9ef67cb5 100644 --- a/plan/exhaust_physical_plans.go +++ b/plan/exhaust_physical_plans.go @@ -601,8 +601,8 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *requiredProp) ([]PhysicalPlan, boo plans = append(plans, join...) } case InnerJoin: - lhsCardinality := p.Children()[0].cardinality() - rhsCardinality := p.Children()[1].cardinality() + lhsCardinality := p.Children()[0].statsInfo().Count() + rhsCardinality := p.Children()[1].statsInfo().Count() leftJoins := p.getIndexJoinByOuterIdx(prop, 0) if leftOuter && leftJoins != nil { diff --git a/plan/plan.go b/plan/plan.go index bc6926ca8973f..d3b7c2eee5e06 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -187,8 +187,6 @@ type LogicalPlan interface { // deriveStats derives statistic info between plans. deriveStats() (*statsInfo, error) - cardinality() float64 - // preparePossibleProperties is only used for join and aggregation. Like group by a,b,c, all permutation of (a,b,c) is // valid, but the ordered indices in leaf plan is limited. So we can get all possible order properties by a pre-walking. // Please make sure that children's method is called though we may not need its return value, @@ -329,20 +327,6 @@ func (p *baseLogicalPlan) extractCorrelatedCols() []*expression.CorrelatedColumn return corCols } -func (p *DataSource) cardinality() float64 { - if p.statsAfterSelect == nil { - return math.MaxFloat64 - } - return p.statsAfterSelect.count -} - -func (p *baseLogicalPlan) cardinality() float64 { - if p.stats == nil { - return math.MaxFloat64 - } - return p.stats.count -} - // PruneColumns implements LogicalPlan interface. func (p *baseLogicalPlan) PruneColumns(parentUsedCols []*expression.Column) { if len(p.children) == 0 {