From 6637b643153c1021f96da4be43137f5608ee96d7 Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Thu, 31 Aug 2023 19:38:09 +0800 Subject: [PATCH 1/3] This is an automated cherry-pick of #46368 Signed-off-by: ti-chi-bot --- planner/core/plan_cost_ver2.go | 10 ++++++++++ planner/core/plan_cost_ver2_test.go | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/planner/core/plan_cost_ver2.go b/planner/core/plan_cost_ver2.go index 1f1569e0c14df..5608a8d84da36 100644 --- a/planner/core/plan_cost_ver2.go +++ b/planner/core/plan_cost_ver2.go @@ -386,8 +386,18 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC } rows := getCardinality(p.children[0], option.CostFlag) +<<<<<<< HEAD N := math.Max(1, float64(p.Count+p.Offset)) rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) +======= + n := max(1, float64(p.Count+p.Offset)) + if n > 10000 { + // It's only used to prevent some extreme cases, e.g. `select * from t order by a limit 18446744073709551615`. + // For normal cases, considering that `rows` may be under-estimated, better to keep `n` unchanged. + n = min(n, rows) + } + rowSize := getAvgRowSize(p.StatsInfo(), p.Schema().Columns) +>>>>>>> 5fbe25ebe35 (planner: adjust N used in TopN cost formula based on the total number of rows (#46368)) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) diff --git a/planner/core/plan_cost_ver2_test.go b/planner/core/plan_cost_ver2_test.go index 37be1316901ef..f6384a14f3cf7 100644 --- a/planner/core/plan_cost_ver2_test.go +++ b/planner/core/plan_cost_ver2_test.go @@ -53,6 +53,18 @@ func testCostQueries(t *testing.T, tk *testkit.TestKit, queries []string) { } } +func TestHugeTopNCost(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t (a int)`) + tk.MustExec(`insert into t values (1)`) + tk.MustExec(`analyze table t`) + plan1 := tk.MustQuery("explain format='verbose' select /*+ limit_to_cop() */ * from t where a=1 order by a limit 1") + plan2 := tk.MustQuery("explain format='verbose' select /*+ limit_to_cop() */ * from t where a=1 order by a limit 1000000000") + require.Equal(t, plan1.Rows()[0][2], plan2.Rows()[0][2]) // should have the same plan cost +} + func TestCostModelVer2(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) From b108ab2c7ea9c02c9170f7c6a414dfa7d696ea9e Mon Sep 17 00:00:00 2001 From: qw4990 Date: Thu, 19 Oct 2023 15:55:20 +0800 Subject: [PATCH 2/3] fixup --- planner/core/plan_cost_ver2.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/planner/core/plan_cost_ver2.go b/planner/core/plan_cost_ver2.go index 5608a8d84da36..0e92e5d47a155 100644 --- a/planner/core/plan_cost_ver2.go +++ b/planner/core/plan_cost_ver2.go @@ -386,18 +386,13 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC } rows := getCardinality(p.children[0], option.CostFlag) -<<<<<<< HEAD - N := math.Max(1, float64(p.Count+p.Offset)) + N := max(1, float64(p.Count+p.Offset)) rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) -======= - n := max(1, float64(p.Count+p.Offset)) - if n > 10000 { + if N > 10000 { // It's only used to prevent some extreme cases, e.g. `select * from t order by a limit 18446744073709551615`. // For normal cases, considering that `rows` may be under-estimated, better to keep `n` unchanged. - n = min(n, rows) + N = min(N, rows) } - rowSize := getAvgRowSize(p.StatsInfo(), p.Schema().Columns) ->>>>>>> 5fbe25ebe35 (planner: adjust N used in TopN cost formula based on the total number of rows (#46368)) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) From fcc560848a69ab40049fa6a9bdd0cad5efdae1b3 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Thu, 19 Oct 2023 15:56:02 +0800 Subject: [PATCH 3/3] fixup --- planner/core/plan_cost_ver2.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planner/core/plan_cost_ver2.go b/planner/core/plan_cost_ver2.go index 0e92e5d47a155..3d63823554570 100644 --- a/planner/core/plan_cost_ver2.go +++ b/planner/core/plan_cost_ver2.go @@ -386,12 +386,12 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC } rows := getCardinality(p.children[0], option.CostFlag) - N := max(1, float64(p.Count+p.Offset)) + N := math.Max(1, float64(p.Count+p.Offset)) rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) if N > 10000 { // It's only used to prevent some extreme cases, e.g. `select * from t order by a limit 18446744073709551615`. // For normal cases, considering that `rows` may be under-estimated, better to keep `n` unchanged. - N = min(N, rows) + N = math.Min(N, rows) } cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType)