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) #7227

Merged
merged 7 commits into from
Aug 2, 2018
35 changes: 21 additions & 14 deletions plan/gen_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,22 +385,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].StatsInfo().Count()
rhsCardinality := p.Children()[1].StatsInfo().Count()

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
38 changes: 19 additions & 19 deletions plan/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (p LogicalSelection) init(ctx sessionctx.Context) *LogicalSelection {
return &p
}

func (p PhysicalSelection) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalSelection {
func (p PhysicalSelection) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalSelection {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeSel, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -122,7 +122,7 @@ func (p LogicalProjection) init(ctx sessionctx.Context) *LogicalProjection {
return &p
}

func (p PhysicalProjection) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalProjection {
func (p PhysicalProjection) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalProjection {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeProj, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -134,7 +134,7 @@ func (p LogicalUnionAll) init(ctx sessionctx.Context) *LogicalUnionAll {
return &p
}

func (p PhysicalUnionAll) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalUnionAll {
func (p PhysicalUnionAll) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalUnionAll {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeUnion, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -146,7 +146,7 @@ func (ls LogicalSort) init(ctx sessionctx.Context) *LogicalSort {
return &ls
}

func (p PhysicalSort) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalSort {
func (p PhysicalSort) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalSort {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeSort, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -164,7 +164,7 @@ func (lt LogicalTopN) init(ctx sessionctx.Context) *LogicalTopN {
return &lt
}

func (p PhysicalTopN) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalTopN {
func (p PhysicalTopN) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalTopN {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeTopN, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -176,7 +176,7 @@ func (p LogicalLimit) init(ctx sessionctx.Context) *LogicalLimit {
return &p
}

func (p PhysicalLimit) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalLimit {
func (p PhysicalLimit) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalLimit {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeLimit, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -188,7 +188,7 @@ func (p LogicalTableDual) init(ctx sessionctx.Context) *LogicalTableDual {
return &p
}

func (p PhysicalTableDual) init(ctx sessionctx.Context, stats *statsInfo) *PhysicalTableDual {
func (p PhysicalTableDual) init(ctx sessionctx.Context, stats *StatsInfo) *PhysicalTableDual {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeDual, &p)
p.stats = stats
return &p
Expand All @@ -199,7 +199,7 @@ func (p LogicalExists) init(ctx sessionctx.Context) *LogicalExists {
return &p
}

func (p PhysicalExists) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalExists {
func (p PhysicalExists) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalExists {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeExists, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -211,7 +211,7 @@ func (p LogicalMaxOneRow) init(ctx sessionctx.Context) *LogicalMaxOneRow {
return &p
}

func (p PhysicalMaxOneRow) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalMaxOneRow {
func (p PhysicalMaxOneRow) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalMaxOneRow {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeMaxOneRow, &p)
p.childrenReqProps = props
p.stats = stats
Expand Down Expand Up @@ -243,7 +243,7 @@ func (p LogicalLock) init(ctx sessionctx.Context) *LogicalLock {
return &p
}

func (p PhysicalLock) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalLock {
func (p PhysicalLock) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalLock {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeLock, &p)
p.childrenReqProps = props
p.stats = stats
Expand All @@ -260,13 +260,13 @@ func (p PhysicalIndexScan) init(ctx sessionctx.Context) *PhysicalIndexScan {
return &p
}

func (p PhysicalMemTable) init(ctx sessionctx.Context, stats *statsInfo) *PhysicalMemTable {
func (p PhysicalMemTable) init(ctx sessionctx.Context, stats *StatsInfo) *PhysicalMemTable {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeMemTableScan, &p)
p.stats = stats
return &p
}

func (p PhysicalHashJoin) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalHashJoin {
func (p PhysicalHashJoin) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalHashJoin {
tp := TypeHashRightJoin
if p.InnerChildIdx == 1 {
tp = TypeHashLeftJoin
Expand All @@ -277,42 +277,42 @@ func (p PhysicalHashJoin) init(ctx sessionctx.Context, stats *statsInfo, props .
return &p
}

func (p PhysicalMergeJoin) init(ctx sessionctx.Context, stats *statsInfo) *PhysicalMergeJoin {
func (p PhysicalMergeJoin) init(ctx sessionctx.Context, stats *StatsInfo) *PhysicalMergeJoin {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeMergeJoin, &p)
p.stats = stats
return &p
}

func (base basePhysicalAgg) init(ctx sessionctx.Context, stats *statsInfo) *basePhysicalAgg {
func (base basePhysicalAgg) init(ctx sessionctx.Context, stats *StatsInfo) *basePhysicalAgg {
base.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeHashAgg, &base)
base.stats = stats
return &base
}

func (base basePhysicalAgg) initForHash(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalHashAgg {
func (base basePhysicalAgg) initForHash(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalHashAgg {
p := &PhysicalHashAgg{base}
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeHashAgg, p)
p.childrenReqProps = props
p.stats = stats
return p
}

func (base basePhysicalAgg) initForStream(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalStreamAgg {
func (base basePhysicalAgg) initForStream(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalStreamAgg {
p := &PhysicalStreamAgg{base}
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeStreamAgg, p)
p.childrenReqProps = props
p.stats = stats
return p
}

func (p PhysicalApply) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalApply {
func (p PhysicalApply) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalApply {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeApply, &p)
p.childrenReqProps = props
p.stats = stats
return &p
}

func (p PhysicalUnionScan) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalUnionScan {
func (p PhysicalUnionScan) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalUnionScan {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeUnionScan, &p)
p.childrenReqProps = props
p.stats = stats
Expand Down Expand Up @@ -348,7 +348,7 @@ func (p PhysicalIndexReader) init(ctx sessionctx.Context) *PhysicalIndexReader {
return &p
}

func (p PhysicalIndexJoin) init(ctx sessionctx.Context, stats *statsInfo, props ...*requiredProp) *PhysicalIndexJoin {
func (p PhysicalIndexJoin) init(ctx sessionctx.Context, stats *StatsInfo, props ...*requiredProp) *PhysicalIndexJoin {
p.basePhysicalPlan = newBasePhysicalPlan(ctx, TypeIndexJoin, &p)
p.childrenReqProps = props
p.stats = stats
Expand Down
4 changes: 2 additions & 2 deletions plan/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ type DataSource struct {
// relevantIndices means the indices match the push down conditions
relevantIndices []bool

// statsAfterSelect is the statsInfo for dataSource and selection.
statsAfterSelect *statsInfo
// statsAfterSelect is the StatsInfo for dataSource and selection.
statsAfterSelect *StatsInfo

statisticTable *statistics.Table

Expand Down
4 changes: 2 additions & 2 deletions plan/physical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func (is *PhysicalIndexScan) addPushedDownSelection(copTask *copTask, p *DataSou
selectivity := path.countAfterIndex / path.countAfterAccess
count = is.stats.count * selectivity
}
stats := &statsInfo{count: count}
stats := &StatsInfo{count: count}
indexSel := PhysicalSelection{Conditions: indexConds}.init(is.ctx, stats)
indexSel.SetChildren(is)
copTask.indexPlan = indexSel
Expand Down Expand Up @@ -565,7 +565,7 @@ func (ds *DataSource) convertToTableScan(prop *requiredProp, path *accessPath) (
return task, nil
}

func (ts *PhysicalTableScan) addPushedDownSelection(copTask *copTask, stats *statsInfo) {
func (ts *PhysicalTableScan) addPushedDownSelection(copTask *copTask, stats *StatsInfo) {
// Add filter condition to table plan now.
if len(ts.filterCondition) > 0 {
copTask.cst += copTask.count() * cpuFactor
Expand Down
15 changes: 10 additions & 5 deletions plan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ type Plan interface {
replaceExprColumns(replace map[string]*expression.Column)

context() sessionctx.Context

// StatsInfo will return the StatsInfo for this plan.
StatsInfo() *StatsInfo
}

// taskType is the type of execution task.
Expand Down Expand Up @@ -161,7 +164,7 @@ type LogicalPlan interface {
pushDownTopN(topN *LogicalTopN) LogicalPlan

// deriveStats derives statistic info between plans.
deriveStats() (*statsInfo, error)
deriveStats() (*StatsInfo, error)

// 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.
Expand Down Expand Up @@ -205,9 +208,6 @@ type PhysicalPlan interface {
// getChildReqProps gets the required property by child index.
getChildReqProps(idx int) *requiredProp

// StatsInfo will return the statsInfo for this plan.
StatsInfo() *statsInfo

// Get all the children.
Children() []PhysicalPlan

Expand Down Expand Up @@ -270,6 +270,11 @@ func (p *baseLogicalPlan) buildKeyInfo() {
}
}

// StatsInfo implements the Plan.StatsInfo interface.
func (p *DataSource) StatsInfo() *StatsInfo {
return p.statsAfterSelect
}

func newBasePlan(ctx sessionctx.Context, tp string) basePlan {
ctx.GetSessionVars().PlanID++
id := ctx.GetSessionVars().PlanID
Expand Down Expand Up @@ -317,7 +322,7 @@ type basePlan struct {
tp string
id int
ctx sessionctx.Context
stats *statsInfo
stats *StatsInfo
}

func (p *basePlan) replaceExprColumns(replace map[string]*expression.Column) {
Expand Down
2 changes: 1 addition & 1 deletion plan/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ func (b *planBuilder) buildCheckIndex(dbName model.CIStr, as *ast.AdminStmt) Pla
Ranges: ranger.FullNewRange(),
KeepOrder: false,
}.init(b.ctx)
is.stats = &statsInfo{}
is.stats = &StatsInfo{}
cop := &copTask{indexPlan: is}
// It's double read case.
ts := PhysicalTableScan{Columns: columns, Table: is.Table}.init(b.ctx)
Expand Down
Loading