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

executor, cmd: refine HashJoinExec for specific JoinType if outer/inner is nil (#8296) #8315

Merged
merged 4 commits into from
Nov 15, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}