Skip to content

Commit

Permalink
planner/core: make TIDB_INLJ to specify the inner table (#8243) (#8298)
Browse files Browse the repository at this point in the history
  • Loading branch information
zz-jason committed Nov 14, 2018
1 parent 03639c3 commit a5afbaf
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 30 deletions.
2 changes: 1 addition & 1 deletion executor/index_lookup_join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (s *testSuite) TestIndexLookupJoinHang(c *C) {
tk.Se.GetSessionVars().IndexJoinBatchSize = 1
tk.Se.GetSessionVars().IndexLookupJoinConcurrency = 1

rs, err := tk.Exec("select /*+ TIDB_INLJ(o, i)*/ * from idxJoinOuter o left join idxJoinInner i on o.a = i.a where o.a in (1, 2) and (i.a - 3) > 0")
rs, err := tk.Exec("select /*+ TIDB_INLJ(i)*/ * from idxJoinOuter o left join idxJoinInner i on o.a = i.a where o.a in (1, 2) and (i.a - 3) > 0")
c.Assert(err, IsNil)
chk := rs.NewChunk()
for i := 0; i < 5; i++ {
Expand Down
22 changes: 11 additions & 11 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ func (s *testSuite) TestJoin(c *C) {

// The physical plans of the two sql are tested at physical_plan_test.go
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
// Test single index reader.
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))

// Test that two conflict hints will return error.
_, err = tk.Exec("select /*+ TIDB_INLJ(t) TIDB_SMJ(t) */ * from t join t1 on t.a=t1.a")
Expand All @@ -169,8 +169,8 @@ func (s *testSuite) TestJoin(c *C) {
tk.MustExec("create table t1(a int, b int)")
tk.MustExec("insert into t values(1, 3), (2, 2), (3, 1)")
tk.MustExec("insert into t1 values(0, 0), (1, 2), (1, 3), (3, 4)")
tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("3 1 3 4", "1 3 1 2", "1 3 1 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("3 1 3 4", "1 3 1 2", "1 3 1 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t right join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("<nil> <nil> 0 0", "3 1 3 4", "1 3 1 2", "1 3 1 3"))

// join reorder will disorganize the resulting schema
Expand All @@ -187,7 +187,7 @@ func (s *testSuite) TestJoin(c *C) {
tk.MustExec("create table t1(a int)")
tk.MustExec("insert into t values(1,2), (5,3), (6,4)")
tk.MustExec("insert into t1 values(1), (2), (3)")
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))

// test issue#4997
tk.MustExec("drop table if exists t1, t2")
Expand Down Expand Up @@ -326,7 +326,7 @@ func (s *testSuite) TestJoinCast(c *C) {
tk.MustExec("create index k1 on t1(c1)")
tk.MustExec("insert into t values(0), (2)")
tk.MustExec("insert into t1 values(0), (9)")
result = tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t left join t1 on t1.c1 = t.c1")
result = tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t left join t1 on t1.c1 = t.c1")
result.Sort().Check(testkit.Rows("0.0 0.00", "2.0 <nil>"))

tk.MustExec("drop table if exists t")
Expand Down Expand Up @@ -672,7 +672,7 @@ func (s *testSuite) TestSubquery(c *C) {
tk.MustExec("CREATE TABLE t1(a int, b int default 0)")
tk.MustExec("create index k1 on t1(a)")
tk.MustExec("INSERT INTO t1 (a) values(1), (2), (3), (4), (5)")
result = tk.MustQuery("select (select /*+ TIDB_INLJ(x1) */ x2.a from t1 x1, t1 x2 where x1.a = t1.a and x1.a = x2.a) from t1")
result = tk.MustQuery("select (select /*+ TIDB_INLJ(x2) */ x2.a from t1 x1, t1 x2 where x1.a = t1.a and x1.a = x2.a) from t1")
result.Check(testkit.Rows("1", "2", "3", "4", "5"))

tk.MustExec("drop table if exists t1, t2")
Expand Down Expand Up @@ -809,7 +809,7 @@ func (s *testSuite) TestIssue5255(c *C) {
tk.MustExec("create table t2(a int primary key)")
tk.MustExec("insert into t1 values(1, '2017-11-29', 2.2)")
tk.MustExec("insert into t2 values(1)")
tk.MustQuery("select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a=t2.a").Check(testkit.Rows("1 2017-11-29 2.2 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t1 join t2 on t1.a=t2.a").Check(testkit.Rows("1 2017-11-29 2.2 1"))
}

func (s *testSuite) TestIssue5278(c *C) {
Expand Down Expand Up @@ -847,7 +847,7 @@ func (s *testSuite) TestIndexLookupJoin(c *C) {
tk.MustExec(`drop table if exists t;`)
tk.MustExec(`create table t(a decimal(6,2), index idx(a));`)
tk.MustExec(`insert into t values(1.01), (2.02), (NULL);`)
tk.MustQuery(`select /*+ TIDB_INLJ(t1) */ t1.a from t t1 join t t2 on t1.a=t2.a order by t1.a;`).Check(testkit.Rows(
tk.MustQuery(`select /*+ TIDB_INLJ(t2) */ t1.a from t t1 join t t2 on t1.a=t2.a order by t1.a;`).Check(testkit.Rows(
`1.01`,
`2.02`,
))
Expand All @@ -856,7 +856,7 @@ func (s *testSuite) TestIndexLookupJoin(c *C) {
tk.MustExec(`create table t(a bigint, b bigint, unique key idx1(a, b));`)
tk.MustExec(`insert into t values(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6);`)
tk.MustExec(`set @@tidb_max_chunk_size = 2;`)
tk.MustQuery(`select /*+ TIDB_INLJ(t1) */ * from t t1 left join t t2 on t1.a = t2.a and t1.b = t2.b + 4;`).Check(testkit.Rows(
tk.MustQuery(`select /*+ TIDB_INLJ(t2) */ * from t t1 left join t t2 on t1.a = t2.a and t1.b = t2.b + 4;`).Check(testkit.Rows(
`1 1 <nil> <nil>`,
`1 2 <nil> <nil>`,
`1 3 <nil> <nil>`,
Expand Down
4 changes: 2 additions & 2 deletions planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,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 @@ -255,15 +255,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 @@ -2007,9 +2007,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 = preferRightAsIndexInner
}
// 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 @@ -372,7 +372,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 @@ -391,33 +391,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)",
},
// 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: "MergeSemiJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
{
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

0 comments on commit a5afbaf

Please sign in to comment.