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

planner/core: make TIDB_INLJ to specify the inner table #8243

Merged
merged 9 commits into from
Nov 13, 2018
4 changes: 2 additions & 2 deletions planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) ([]Phys
return nil, false
}
plans := make([]PhysicalPlan, 0, 2)
leftOuter := (p.preferJoinType & preferLeftAsIndexOuter) > 0
rightOuter := (p.preferJoinType & preferRightAsIndexOuter) > 0
rightOuter := (p.preferJoinType & preferLeftAsIndexInner) > 0
leftOuter := (p.preferJoinType & preferRightAsIndexInner) > 0
switch p.JoinType {
case SemiJoin, AntiSemiJoin, LeftOuterSemiJoin, AntiLeftOuterSemiJoin, LeftOuterJoin:
join := p.getIndexJoinByOuterIdx(prop, 0)
Expand Down
11 changes: 5 additions & 6 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,15 @@ func (p *LogicalJoin) setPreferredJoinType(hintInfo *tableHintInfo) error {
p.preferJoinType |= preferHashJoin
}
if hintInfo.ifPreferINLJ(lhsAlias) {
p.preferJoinType |= preferLeftAsIndexOuter
p.preferJoinType |= preferLeftAsIndexInner
}
if hintInfo.ifPreferINLJ(rhsAlias) {
p.preferJoinType |= preferRightAsIndexOuter
p.preferJoinType |= preferRightAsIndexInner
}

// If there're multiple join types and one of them is not index join hint,
// then there is a conflict of join types.
if bits.OnesCount(p.preferJoinType) > 1 && (p.preferJoinType^preferRightAsIndexOuter^preferLeftAsIndexOuter) > 0 {
if bits.OnesCount(p.preferJoinType) > 1 && (p.preferJoinType^preferRightAsIndexInner^preferLeftAsIndexInner) > 0 {
return errors.New("Join hints are conflict, you can only specify one type of join")
}
return nil
Expand Down Expand Up @@ -2027,9 +2027,8 @@ func (b *PlanBuilder) buildSemiJoin(outerPlan, innerPlan LogicalPlan, onConditio
if b.TableHints().ifPreferHashJoin(outerAlias, innerAlias) {
joinPlan.preferJoinType |= preferHashJoin
}
// semi join's outer is always the left side.
if b.TableHints().ifPreferINLJ(outerAlias) {
joinPlan.preferJoinType = preferLeftAsIndexOuter
if b.TableHints().ifPreferINLJ(innerAlias) {
joinPlan.preferJoinType = preferLeftAsIndexInner
}
// If there're multiple join hints, they're conflict.
if bits.OnesCount(joinPlan.preferJoinType) > 1 {
Expand Down
4 changes: 2 additions & 2 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func (tp JoinType) String() string {
}

const (
preferLeftAsIndexOuter = 1 << iota
preferRightAsIndexOuter
preferLeftAsIndexInner = 1 << iota
preferRightAsIndexInner
preferHashJoin
preferMergeJoin
)
Expand Down
16 changes: 8 additions & 8 deletions planner/core/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
},
// Test Index Join + TableScan + Rotate.
{
sql: "select /*+ TIDB_INLJ(t2) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
sql: "select /*+ TIDB_INLJ(t1) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.c,t1.a)->Projection",
},
// Test Index Join + OuterJoin + TableScan.
Expand All @@ -383,33 +383,33 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
},
// Test Index Join failed.
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 right outer join t t2 on t1.a = t2.b",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 right outer join t t2 on t1.a = t2.b",
best: "RightHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.b)",
},
// Test Semi Join hint success.
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)->Projection",
},
// Test Semi Join hint fail.
{
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)",
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.a,t1.a)->Projection",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.c=t2.c and t1.f=t2.f",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.c=t2.c and t1.f=t2.f",
best: "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(t1.c,t2.c)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.a = t2.a and t1.f=t2.f",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a = t2.a and t1.f=t2.f",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.f=t2.f and t1.a=t2.a",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.f=t2.f and t1.a=t2.a",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.a=t2.a and t2.a in (1, 2)",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a=t2.a and t2.a in (1, 2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t)->Sel([in(t2.a, 1, 2)]))}(t1.a,t2.a)",
},
}
Expand Down