planner: remove task argument from IndexHashJoin.GetCost and IndexMergeJoin.GetCost (#33935)

close pingcap/tidb#33934
This commit is contained in:
Yuanjia Zhang
2022-04-13 19:14:36 +08:00
committed by GitHub
parent 8f5582a1ef
commit 19b9f53d5e
2 changed files with 25 additions and 10 deletions

View File

@ -5304,6 +5304,23 @@ func TestIndexJoinCost(t *testing.T) {
` ├─Selection_9(Build) 1.25 0.00 cop[tikv] not(isnull(test.t_inner_idx.a))`,
` │ └─IndexRangeScan_7 1.25 0.00 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:false, stats:pseudo`,
` └─TableRowIDScan_8(Probe) 1.25 0.00 cop[tikv] table:t_inner_idx keep order:false, stats:pseudo`))
tk.MustQuery("explain format=verbose select /*+ inl_hash_join(t_outer, t_inner_idx) */ t_inner_idx.a from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a").Check(testkit.Rows(
`IndexHashJoin_12 12487.50 221872.19 root inner join, inner:IndexReader_9, outer key:test.t_outer.a, inner key:test.t_inner_idx.a, equal cond:eq(test.t_outer.a, test.t_inner_idx.a)`,
`├─TableReader_20(Build) 9990.00 36412.58 root data:Selection_19`,
`│ └─Selection_19 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`,
`│ └─TableFullScan_18 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`,
`└─IndexReader_9(Probe) 1.25 4.56 root index:Selection_8`,
` └─Selection_8 1.25 0.00 cop[tikv] not(isnull(test.t_inner_idx.a))`,
` └─IndexRangeScan_7 1.25 0.00 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:false, stats:pseudo`))
tk.MustQuery("explain format=verbose select /*+ inl_merge_join(t_outer, t_inner_idx) */ t_inner_idx.a from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a").Check(testkit.Rows(
`IndexMergeJoin_17 12487.50 215890.68 root inner join, inner:IndexReader_15, outer key:test.t_outer.a, inner key:test.t_inner_idx.a`,
`├─TableReader_20(Build) 9990.00 36412.58 root data:Selection_19`,
`│ └─Selection_19 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`,
`│ └─TableFullScan_18 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`,
`└─IndexReader_15(Probe) 1.25 4.56 root index:Selection_14`,
` └─Selection_14 1.25 0.00 cop[tikv] not(isnull(test.t_inner_idx.a))`,
` └─IndexRangeScan_13 1.25 0.00 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:true, stats:pseudo`))
}
func TestHeuristicIndexSelection(t *testing.T) {

View File

@ -295,16 +295,15 @@ func (p *PhysicalIndexMergeJoin) attach2Task(tasks ...task) task {
}
t := &rootTask{
p: p,
cst: p.GetCost(outerTask, innerTask),
cst: p.GetCost(outerTask.count(), innerTask.count(), outerTask.cost(), innerTask.cost()),
}
p.cost = t.cost()
return t
}
// GetCost computes the cost of index merge join operator and its children.
func (p *PhysicalIndexMergeJoin) GetCost(outerTask, innerTask task) float64 {
func (p *PhysicalIndexMergeJoin) GetCost(outerCnt, innerCnt, outerCost, innerCost float64) float64 {
var cpuCost float64
outerCnt, innerCnt := outerTask.count(), innerTask.count()
sessVars := p.ctx.GetSessionVars()
// Add the cost of evaluating outer filter, since inner filter of index join
// is always empty, we can simply tell whether outer filter is empty using the
@ -360,8 +359,8 @@ func (p *PhysicalIndexMergeJoin) GetCost(outerTask, innerTask task) float64 {
// So the memory cost consider the results size for each batch.
memoryCost := innerConcurrency * (batchSize * avgProbeCnt) * sessVars.MemoryFactor
innerPlanCost := outerCnt * innerTask.cost()
return outerTask.cost() + innerPlanCost + cpuCost + memoryCost
innerPlanCost := outerCnt * innerCost
return outerCost + innerPlanCost + cpuCost + memoryCost
}
func (p *PhysicalIndexHashJoin) attach2Task(tasks ...task) task {
@ -374,16 +373,15 @@ func (p *PhysicalIndexHashJoin) attach2Task(tasks ...task) task {
}
t := &rootTask{
p: p,
cst: p.GetCost(outerTask, innerTask),
cst: p.GetCost(outerTask.count(), innerTask.count(), outerTask.cost(), innerTask.cost()),
}
p.cost = t.cost()
return t
}
// GetCost computes the cost of index merge join operator and its children.
func (p *PhysicalIndexHashJoin) GetCost(outerTask, innerTask task) float64 {
func (p *PhysicalIndexHashJoin) GetCost(outerCnt, innerCnt, outerCost, innerCost float64) float64 {
var cpuCost float64
outerCnt, innerCnt := outerTask.count(), innerTask.count()
sessVars := p.ctx.GetSessionVars()
// Add the cost of evaluating outer filter, since inner filter of index join
// is always empty, we can simply tell whether outer filter is empty using the
@ -437,8 +435,8 @@ func (p *PhysicalIndexHashJoin) GetCost(outerTask, innerTask task) float64 {
// since the executor is pipelined and not all workers are always in full load.
memoryCost := concurrency * (batchSize * distinctFactor) * innerCnt * sessVars.MemoryFactor
// Cost of inner child plan, i.e, mainly I/O and network cost.
innerPlanCost := outerCnt * innerTask.cost()
return outerTask.cost() + innerPlanCost + cpuCost + memoryCost
innerPlanCost := outerCnt * innerCost
return outerCost + innerPlanCost + cpuCost + memoryCost
}
func (p *PhysicalIndexJoin) attach2Task(tasks ...task) task {