From 4df3389c263d5acd1c19155f280eb015b757cd76 Mon Sep 17 00:00:00 2001 From: tpp <146148086+terry1purcell@users.noreply.github.com> Date: Sun, 29 Sep 2024 16:35:57 +0700 Subject: [PATCH] planner: Set minimum cost to avoid parent multiplication cost discrepancies (#56387) ref pingcap/tidb#55126 --- .../testdata/plan_normalized_suite_out.json | 16 ++++++++-------- pkg/planner/core/plan_cost_ver2.go | 4 ++-- pkg/planner/core/task.go | 4 ++-- pkg/planner/util/costusage/cost_misc.go | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/planner/core/casetest/testdata/plan_normalized_suite_out.json b/pkg/planner/core/casetest/testdata/plan_normalized_suite_out.json index 0658b348ca..eace2a1ef0 100644 --- a/pkg/planner/core/casetest/testdata/plan_normalized_suite_out.json +++ b/pkg/planner/core/casetest/testdata/plan_normalized_suite_out.json @@ -419,8 +419,8 @@ " TableReader root ", " └─ExchangeSender cop[tiflash] ", " └─Projection cop[tiflash] test.t1.a", - " └─Selection cop[tiflash] gt(test.t1.b, ?)", - " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.a, ?), keep order:false" + " └─Selection cop[tiflash] gt(test.t1.a, ?)", + " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.b, ?), keep order:false" ] }, { @@ -428,8 +428,8 @@ "Plan": [ " TableReader root ", " └─ExchangeSender cop[tiflash] ", - " └─Selection cop[tiflash] gt(test.t1.b, ?)", - " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.a, ?), gt(test.t1.c, ?), keep order:false" + " └─Selection cop[tiflash] gt(test.t1.c, ?)", + " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.a, ?), gt(test.t1.b, ?), keep order:false" ] }, { @@ -445,8 +445,8 @@ "Plan": [ " TableReader root ", " └─ExchangeSender cop[tiflash] ", - " └─Selection cop[tiflash] gt(test.t1.b, ?), or(lt(test.t1.a, ?), lt(test.t1.b, ?))", - " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.a, ?), keep order:false" + " └─Selection cop[tiflash] gt(test.t1.a, ?), or(lt(test.t1.a, ?), lt(test.t1.b, ?))", + " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.b, ?), keep order:false" ] }, { @@ -454,8 +454,8 @@ "Plan": [ " TableReader root ", " └─ExchangeSender cop[tiflash] ", - " └─Selection cop[tiflash] gt(test.t1.a, ?), gt(test.t1.c, ?), or(lt(test.t1.a, ?), lt(test.t1.b, ?))", - " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.b, ?), keep order:false" + " └─Selection cop[tiflash] gt(test.t1.b, ?), gt(test.t1.c, ?), or(lt(test.t1.a, ?), lt(test.t1.b, ?))", + " └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.a, ?), keep order:false" ] }, { diff --git a/pkg/planner/core/plan_cost_ver2.go b/pkg/planner/core/plan_cost_ver2.go index 238e842d81..75f010fe66 100644 --- a/pkg/planner/core/plan_cost_ver2.go +++ b/pkg/planner/core/plan_cost_ver2.go @@ -820,7 +820,7 @@ func scanCostVer2(option *optimizetrace.PlanCostOption, rows, rowSize float64, s } return costusage.NewCostVer2(option, scanFactor, // rows * log(row-size) * scanFactor, log2 from experiments - rows*math.Log2(rowSize)*scanFactor.Value, + rows*max(math.Log2(rowSize), 0)*scanFactor.Value, func() string { return fmt.Sprintf("scan(%v*logrowsize(%v)*%v)", rows, rowSize, scanFactor) }) } @@ -874,7 +874,7 @@ func orderCostVer2(option *optimizetrace.PlanCostOption, rows, n float64, byItem rows*float64(numFuncs)*cpuFactor.Value, func() string { return fmt.Sprintf("exprCPU(%v*%v*%v)", rows, numFuncs, cpuFactor) }) orderCost := costusage.NewCostVer2(option, cpuFactor, - rows*math.Log2(n)*cpuFactor.Value, + max(rows*math.Log2(n), 0)*cpuFactor.Value, func() string { return fmt.Sprintf("orderCPU(%v*log(%v)*%v)", rows, n, cpuFactor) }) return costusage.SumCostVer2(exprCost, orderCost) } diff --git a/pkg/planner/core/task.go b/pkg/planner/core/task.go index 40b3383b4c..14c49e3ae7 100644 --- a/pkg/planner/core/task.go +++ b/pkg/planner/core/task.go @@ -179,11 +179,11 @@ func (p *PhysicalIndexJoin) Attach2Task(tasks ...base.Task) base.Task { // RowSize for cost model ver2 is simplified, always use this function to calculate row size. func getAvgRowSize(stats *property.StatsInfo, cols []*expression.Column) (size float64) { if stats.HistColl != nil { - size = cardinality.GetAvgRowSizeDataInDiskByRows(stats.HistColl, cols) + size = max(cardinality.GetAvgRowSizeDataInDiskByRows(stats.HistColl, cols), 0) } else { // Estimate using just the type info. for _, col := range cols { - size += float64(chunk.EstimateTypeWidth(col.GetStaticType())) + size += max(float64(chunk.EstimateTypeWidth(col.GetStaticType())), 0) } } return diff --git a/pkg/planner/util/costusage/cost_misc.go b/pkg/planner/util/costusage/cost_misc.go index 282ea6363f..472c06cd08 100644 --- a/pkg/planner/util/costusage/cost_misc.go +++ b/pkg/planner/util/costusage/cost_misc.go @@ -59,7 +59,7 @@ type CostVer2 struct { // GetCost returns the cost value of the costVer2 func (c *CostVer2) GetCost() float64 { - return c.cost + return max(c.cost, 0) } // GetTrace returns the trace of current costVer2