diff --git a/plan/dag_plan_test.go b/plan/dag_plan_test.go index 5ef47b62de..a705e8a578 100644 --- a/plan/dag_plan_test.go +++ b/plan/dag_plan_test.go @@ -191,13 +191,21 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) { sql: "select * from t t1 join t t2 on t1.a = t2.c_str", best: "LeftHashJoin{TableReader(Table(t))->Projection->TableReader(Table(t))->Projection}(cast(t1.a),cast(t2.c_str))->Projection", }, + { + sql: "select * from t t1 join t t2 on t1.b = t2.a", + best: "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.b,t2.a)", + }, { sql: "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a", best: "MergeJoin{MergeJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)->TableReader(Table(t))}(t1.a,t3.a)", }, + { + sql: "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.b = t3.a", + best: "LeftHashJoin{MergeJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)->TableReader(Table(t))}(t1.b,t3.a)", + }, { sql: "select * from t t1 join t t2 on t1.b = t2.a order by t1.a", - best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.b,t2.a)->Sort", + best: "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.b,t2.a)->Sort", }, { sql: "select * from t t1 join t t2 on t1.b = t2.a order by t1.a limit 1", @@ -217,7 +225,7 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) { }, { sql: "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a and t1.b = 1 and t3.c = 1", - best: "IndexJoin{IndexJoin{TableReader(Table(t)->Sel([eq(t1.b, 1)]))->TableReader(Table(t))}(t1.a,t2.a)->TableReader(Table(t)->Sel([eq(t3.c, 1)]))}(t1.a,t3.a)", + best: "LeftHashJoin{IndexJoin{TableReader(Table(t)->Sel([eq(t1.b, 1)]))->TableReader(Table(t))}(t1.a,t2.a)->IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))}(t1.a,t3.a)", }, { sql: "select * from t where t.c in (select b from t s where s.a = t.a)", @@ -231,7 +239,7 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) { // Merge Join will no longer enforce a sort. If a hint doesn't take effect, we will choose other types of join. { sql: "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.b", - best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.b,t1.a)->Projection", + best: "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.b)", }, // Test Single Merge Join + Sort. { @@ -301,7 +309,7 @@ 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", - best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.b,t1.a)->Projection", + best: "RightHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.b)", }, } for _, tt := range tests { diff --git a/plan/explain_test.go b/plan/explain_test.go index 2aac83d42b..571c99371b 100644 --- a/plan/explain_test.go +++ b/plan/explain_test.go @@ -98,11 +98,10 @@ func (s *testExplainSuite) TestExplain(c *C) { "select * from t1 left join t2 on t1.c2 = t2.c1 where t1.c1 > 1", []string{ "TableScan_22 cop table:t1, range:[2,+inf), keep order:false", - "TableReader_23 IndexJoin_7 root data:TableScan_22", - "IndexScan_33 cop table:t2, index:c1, range:[,+inf], out of order:false", - "TableScan_34 cop table:t2, keep order:false", - "IndexLookUp_35 IndexJoin_7 root index:IndexScan_33, table:TableScan_34", - "IndexJoin_7 root outer:TableReader_23, outer key:test.t1.c2, inner key:test.t2.c1", + "TableReader_23 HashLeftJoin_8 root data:TableScan_22", + "TableScan_37 cop table:t2, range:(-inf,+inf), keep order:false", + "TableReader_38 HashLeftJoin_8 root data:TableScan_37", + "HashLeftJoin_8 root left outer join, small:TableReader_38, equal:[eq(test.t1.c2, test.t2.c1)]", }, }, { @@ -125,13 +124,13 @@ func (s *testExplainSuite) TestExplain(c *C) { { "select count(b.c2) from t1 a, t2 b where a.c1 = b.c2 group by a.c1", []string{ + "TableScan_25 cop table:a, range:(-inf,+inf), keep order:false", + "TableReader_26 HashLeftJoin_10 root data:TableScan_25", "TableScan_17 HashAgg_16 cop table:b, range:(-inf,+inf), keep order:false", "HashAgg_16 cop type:complete, group by:b.c2, funcs:count(b.c2), firstrow(b.c2)", "TableReader_19 HashAgg_18 root data:HashAgg_16", - "HashAgg_18 IndexJoin_9 root type:final, group by:, funcs:count(col_0), firstrow(col_1)", - "TableScan_12 cop table:a, range:(-inf,+inf), keep order:true", - "TableReader_22 IndexJoin_9 root data:TableScan_12", - "IndexJoin_9 Projection_8 root outer:TableReader_22, outer key:b.c2, inner key:a.c1", + "HashAgg_18 HashLeftJoin_10 root type:final, group by:, funcs:count(col_0), firstrow(col_1)", + "HashLeftJoin_10 Projection_8 root inner join, small:HashAgg_18, equal:[eq(a.c1, b.c2)]", "Projection_8 root cast(join_agg_0)", }, }, diff --git a/plan/task.go b/plan/task.go index b9fe4f7843..bafde717c1 100644 --- a/plan/task.go +++ b/plan/task.go @@ -166,7 +166,7 @@ func (p *PhysicalHashJoin) getCost(lCnt, rCnt float64) float64 { if smallTableCnt <= 1 { smallTableCnt = 1 } - return (lCnt + rCnt) * (1 + math.Log2(smallTableCnt)) + return (lCnt + rCnt) * (1 + math.Log2(smallTableCnt)/float64(p.Concurrency)) } func (p *PhysicalHashJoin) attach2Task(tasks ...task) task {