Skip to content

Commit

Permalink
executor, cmd: refine HashJoinExec for specific JoinType if outer/inn…
Browse files Browse the repository at this point in the history
…er is nil (pingcap#8296)
  • Loading branch information
XuHuaiyu committed Nov 14, 2018
1 parent f0df5c6 commit 2fef69e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ y.output
profile.coverprofile
explain_test
cmd/explaintest/explain-test.out
cmd/explaintest/explaintest_tidb-server
_tools/
*.fail.go
7 changes: 5 additions & 2 deletions executor/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,11 @@ func (e *HashJoinExec) fetchOuterChunks(ctx context.Context) {
}
return
}

if !hasWaitedForInner {
if outerResult.NumRows() == 0 {
e.finished.Store(true)
return
}
jobFinished, innerErr := e.wait4Inner()
if innerErr != nil {
e.joinResultCh <- &hashjoinWorkerResult{
Expand Down Expand Up @@ -241,7 +244,7 @@ func (e *HashJoinExec) wait4Inner() (finished bool, err error) {
return false, errors.Trace(err)
}
}
if e.hashTable.Len() == 0 && e.joinType == plannercore.InnerJoin {
if e.hashTable.Len() == 0 && (e.joinType == plannercore.InnerJoin || e.joinType == plannercore.SemiJoin) {
return true, nil
}
return false, nil
Expand Down
56 changes: 56 additions & 0 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -921,3 +921,59 @@ func (s *testSuite) TestEmbeddedOuterJoin(c *C) {
tk.MustQuery("select * from (t1 left join t2 on t1.a = t2.a) left join (t2 t3 left join t2 t4 on t3.a = t4.a) on t2.b = 1").
Check(testkit.Rows("1 1 <nil> <nil> <nil> <nil> <nil> <nil>"))
}

func (s *testSuite) TestHashJoin(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, b int);")
tk.MustExec("create table t2(a int, b int);")
tk.MustExec("insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);")
tk.MustQuery("select count(*) from t1").Check(testkit.Rows("5"))
tk.MustQuery("select count(*) from t2").Check(testkit.Rows("0"))
tk.MustExec("set @@tidb_max_chunk_size=1;")
result := tk.MustQuery("explain analyze select /*+ TIDB_HJ(t1, t2) */ * from t1 where exists (select a from t2 where t1.a = t2.a);")
// id count task operator info execution info
// HashLeftJoin_9 8000.00 root semi join, inner:TableReader_13, equal:[eq(test.t1.a, test.t2.a)] time:1.036712ms, loops:1, rows:0
// ├─TableReader_11 10000.00 root data:TableScan_10 time:441.096µs, loops:1, rows:1
// │ └─TableScan_10 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo
// └─TableReader_13 10000.00 root data:TableScan_12 time:212.376µs, loops:1, rows:0
// └─TableScan_12 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo
row := result.Rows()
c.Assert(len(row), Equals, 5)
outerExecInfo := row[1][4].(string)
c.Assert(outerExecInfo[len(outerExecInfo)-1:], Equals, "1")
innerExecInfo := row[3][4].(string)
c.Assert(innerExecInfo[len(innerExecInfo)-1:], Equals, "0")

tk.MustExec("insert into t2 select * from t1;")
tk.MustExec("delete from t1;")
tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0"))
tk.MustQuery("select count(*) from t2").Check(testkit.Rows("5"))
result = tk.MustQuery("explain analyze select /*+ TIDB_HJ(t1, t2) */ * from t1 where not exists (select a from t2 where t1.a = t2.a);")
// id count task operator info execution info
// HashLeftJoin_9 8000.00 root anti semi join, inner:TableReader_13, equal:[eq(test.t1.a, test.t2.a)] time:534.643µs, loops:1, rows:0
// ├─TableReader_11 10000.00 root data:TableScan_10 time:35.042µs, loops:1, rows:0
// │ └─TableScan_10 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo
// └─TableReader_13 10000.00 root data:TableScan_12 time:0s, loops:0, rows:0
// └─TableScan_12 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo
row = result.Rows()
c.Assert(len(row), Equals, 5)
outerExecInfo = row[1][4].(string)
c.Assert(outerExecInfo[len(outerExecInfo)-1:], Equals, "0")
innerExecInfo = row[3][4].(string)
c.Assert(innerExecInfo[len(innerExecInfo)-1:], LessEqual, "5")

result = tk.MustQuery("explain select /*+ TIDB_HJ(t1, t2) */ * from t1 left outer join t2 on t1.a = t2.a;")
// id count task operator info execution info
// HashLeftJoin_6 12500.00 root left outer join, inner:TableReader_10, equal:[eq(test.t1.a, test.t2.a)] time:502.553µs, loops:1, rows:0
// ├─TableReader_8 10000.00 root data:TableScan_7 time:27.302µs, loops:1, rows:0
// │ └─TableScan_7 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo
// └─TableReader_10 10000.00 root data:TableScan_9 time:0s, loops:0, rows:0
// └─TableScan_9 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo
c.Assert(len(row), Equals, 5)
outerExecInfo = row[1][4].(string)
c.Assert(outerExecInfo[len(outerExecInfo)-1:], Equals, "0")
innerExecInfo = row[3][4].(string)
c.Assert(innerExecInfo[len(innerExecInfo)-1:], LessEqual, "5")
}

0 comments on commit 2fef69e

Please sign in to comment.