Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plan: always chose the smaller child as outer for IndexJoin #7019

Merged
merged 8 commits into from
Jul 31, 2018
35 changes: 21 additions & 14 deletions plan/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge master and you can use p.Childrend()[0].StatsInfo().Count() now.

rhsCardinality := p.Children()[1].cardinality()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


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
}
Expand Down
16 changes: 16 additions & 0 deletions plan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ type LogicalPlan interface {
// deriveStats derives statistic info between plans.
deriveStats() (*statsInfo, error)

cardinality() float64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this.


// 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,
Expand Down Expand Up @@ -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 {
Expand Down