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

planner: update some UTs from cost model1 to model2 #39065

Merged
merged 26 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions bindinfo/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ func TestNotEvolvePlanForReadStorageHint(t *testing.T) {

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, index idx_a(a), index idx_b(b))")
tk.MustExec("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)")
Expand Down Expand Up @@ -918,6 +919,7 @@ func TestBindingWithIsolationRead(t *testing.T) {

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, index idx_a(a), index idx_b(b))")
tk.MustExec("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)")
Expand Down
1 change: 1 addition & 0 deletions executor/explain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ func TestCheckActRowsWithUnistore(t *testing.T) {
// testSuite1 use default mockstore which is unistore
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop table if exists t_unistore_act_rows")
tk.MustExec("create table t_unistore_act_rows(a int, b int, index(a, b))")
tk.MustExec("insert into t_unistore_act_rows values (1, 0), (1, 0), (2, 0), (2, 1)")
Expand Down
9 changes: 5 additions & 4 deletions executor/explainfor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ func TestSetOperations4PlanCache(t *testing.T) {
func TestSPM4PlanCache(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec(`set tidb_enable_prepared_plan_cache=1`)

tk.MustExec("use test")
Expand All @@ -990,8 +991,8 @@ func TestSPM4PlanCache(t *testing.T) {
tk.MustExec("admin reload bindings;")

res := tk.MustQuery("explain format = 'brief' select * from t;")
require.Regexp(t, ".*TableReader.*", res.Rows()[0][0])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected, IndexScan is always better than TableScan.

require.Regexp(t, ".*TableFullScan.*", res.Rows()[1][0])
require.Regexp(t, ".*IndexReader.*", res.Rows()[0][0])
require.Regexp(t, ".*IndexFullScan.*", res.Rows()[1][0])

tk.MustExec("prepare stmt from 'select * from t;';")
tk.MustQuery("execute stmt;").Check(testkit.Rows())
Expand All @@ -1000,8 +1001,8 @@ func TestSPM4PlanCache(t *testing.T) {
ps := []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.Regexp(t, ".*TableReader.*", res.Rows()[0][0])
require.Regexp(t, ".*TableFullScan.*", res.Rows()[1][0])
require.Regexp(t, ".*IndexReader.*", res.Rows()[0][0])
require.Regexp(t, ".*IndexFullScan.*", res.Rows()[1][0])

tk.MustExec("create global binding for select * from t using select * from t use index(idx_a);")

Expand Down
6 changes: 3 additions & 3 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1357,7 +1357,7 @@ func TestIndexLookupJoin(t *testing.T) {
tk.MustExec("analyze table s;")

tk.MustQuery("desc format = 'brief' select /*+ TIDB_INLJ(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows(
"StreamAgg 1.00 root funcs:count(1)->Column#6",
"HashAgg 1.00 root funcs:count(1)->Column#6",
"└─IndexJoin 64.00 root inner join, inner:IndexReader, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), other cond:lt(test.s.b, test.t.b)",
" ├─TableReader(Build) 64.00 root data:Selection",
" │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))",
Expand All @@ -1370,7 +1370,7 @@ func TestIndexLookupJoin(t *testing.T) {
tk.MustQuery("select /*+ TIDB_INLJ(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64"))

tk.MustQuery("desc format = 'brief' select /*+ INL_MERGE_JOIN(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows(
"StreamAgg 1.00 root funcs:count(1)->Column#6",
"HashAgg 1.00 root funcs:count(1)->Column#6",
"└─IndexMergeJoin 64.00 root inner join, inner:IndexReader, outer key:test.t.a, inner key:test.s.a, other cond:lt(test.s.b, test.t.b)",
" ├─TableReader(Build) 64.00 root data:Selection",
" │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))",
Expand All @@ -1384,7 +1384,7 @@ func TestIndexLookupJoin(t *testing.T) {
tk.MustQuery("select /*+ INL_MERGE_JOIN(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64"))

tk.MustQuery("desc format = 'brief' select /*+ INL_HASH_JOIN(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows(
"StreamAgg 1.00 root funcs:count(1)->Column#6",
"HashAgg 1.00 root funcs:count(1)->Column#6",
"└─IndexHashJoin 64.00 root inner join, inner:IndexReader, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), other cond:lt(test.s.b, test.t.b)",
" ├─TableReader(Build) 64.00 root data:Selection",
" │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))",
Expand Down
30 changes: 14 additions & 16 deletions executor/partition_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) {
tk.MustExec("create database test_global_stats")
tk.MustExec("use test_global_stats")
tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'")
tk.MustExec("set tidb_cost_model_version=2")

// hash and range and list partition
tk.MustExec("create table thash(a int, b int, key(a)) partition by hash(a) partitions 4")
Expand Down Expand Up @@ -953,10 +954,9 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) {
tk.MustExec("analyze table trange")
tk.MustExec("analyze table tlist")

// after analyzing, the planner will use the Index(a)
tk.MustIndexLookup("select * from thash where a<100")
tk.MustIndexLookup("select * from trange where a<100")
tk.MustIndexLookup("select * from tlist where a<1")
require.True(t, tk.HasPlan("select * from thash where a<100", "TableFullScan"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected, model2 prefers to use Scan instead of Lookup to avoid triggering too many double-read requests.

require.True(t, tk.HasPlan("select * from trange where a<100", "TableFullScan"))
require.True(t, tk.HasPlan("select * from tlist where a<1", "TableFullScan"))

// create SQL bindings
tk.MustExec("create session binding for select * from thash where a<100 using select * from thash ignore index(a) where a<100")
Expand All @@ -973,10 +973,9 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) {
tk.MustExec("drop session binding for select * from trange where a<100")
tk.MustExec("drop session binding for select * from tlist where a<100")

// use Index(a) again
tk.MustIndexLookup("select * from thash where a<100")
tk.MustIndexLookup("select * from trange where a<100")
tk.MustIndexLookup("select * from tlist where a<1")
require.True(t, tk.HasPlan("select * from thash where a<100", "TableFullScan"))
require.True(t, tk.HasPlan("select * from trange where a<100", "TableFullScan"))
require.True(t, tk.HasPlan("select * from tlist where a<1", "TableFullScan"))
}

func TestPartitionTableWithDifferentJoin(t *testing.T) {
Expand Down Expand Up @@ -3435,6 +3434,7 @@ func TestPartitionTableExplain(t *testing.T) {

tk := testkit.NewTestKit(t, store)
tk.MustExec("create database TestPartitionTableExplain")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("use TestPartitionTableExplain")
tk.MustExec("set @@tidb_partition_prune_mode = 'static'")
tk.MustExec(`create table t (a int primary key, b int, key (b)) partition by hash(a) (partition P0, partition p1, partition P2)`)
Expand Down Expand Up @@ -3571,22 +3571,20 @@ func TestPartitionTableExplain(t *testing.T) {
"└─IndexRangeScan 2.00 cop[tikv] table:t, index:b(b) range:[2,2], [3,3], keep order:false"))
tk.MustQuery(`explain format = 'brief' select * from t,t2 where t2.a = 1 and t2.b = t.b`).Check(testkit.Rows(
"Projection 1.00 root testpartitiontableexplain.t.a, testpartitiontableexplain.t.b, testpartitiontableexplain.t2.a, testpartitiontableexplain.t2.b",
"└─IndexJoin 1.00 root inner join, inner:IndexReader, outer key:testpartitiontableexplain.t2.b, inner key:testpartitiontableexplain.t.b, equal cond:eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected, model2 prefers to avoid using double-read IndexJoin.

"└─HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)]",
" ├─TableReader(Build) 1.00 root data:Selection",
" │ └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))",
" │ └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false",
" └─IndexReader(Probe) 1.00 root partition:all index:Selection",
" └─Selection 1.00 cop[tikv] not(isnull(testpartitiontableexplain.t.b))",
" └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range: decided by [eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)], keep order:false"))
" └─IndexReader(Probe) 3.00 root partition:all index:IndexFullScan",
" └─IndexFullScan 3.00 cop[tikv] table:t, index:b(b) keep order:false"))
tk.MustQuery(`explain format = 'brief' select * from t partition (p1),t2 where t2.a = 1 and t2.b = t.b`).Check(testkit.Rows(
"Projection 1.00 root testpartitiontableexplain.t.a, testpartitiontableexplain.t.b, testpartitiontableexplain.t2.a, testpartitiontableexplain.t2.b",
"└─IndexJoin 1.00 root inner join, inner:IndexReader, outer key:testpartitiontableexplain.t2.b, inner key:testpartitiontableexplain.t.b, equal cond:eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)",
"└─HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)]",
" ├─TableReader(Build) 1.00 root data:Selection",
" │ └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))",
" │ └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false",
" └─IndexReader(Probe) 1.00 root partition:p1 index:Selection",
" └─Selection 1.00 cop[tikv] not(isnull(testpartitiontableexplain.t.b))",
" └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range: decided by [eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)], keep order:false"))
" └─IndexReader(Probe) 3.00 root partition:p1 index:IndexFullScan",
" └─IndexFullScan 3.00 cop[tikv] table:t, index:b(b) keep order:false"))
tk.MustQuery(`explain format = 'brief' select * from t,t2 where t2.a = 1 and t2.b = t.b and t.a = 1`).Check(testkit.Rows(
"HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)]",
"├─TableReader(Build) 1.00 root data:Selection",
Expand Down
1 change: 1 addition & 0 deletions executor/tiflashtest/tiflash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,7 @@ func TestForbidTiFlashIfExtraPhysTableIDIsNeeded(t *testing.T) {
require.NoError(t, err)
tk.MustExec("set tidb_partition_prune_mode=dynamic")
tk.MustExec("set tidb_enforce_mpp=1")
tk.MustExec("set tidb_cost_model_version=2")

rows := tk.MustQuery("explain select count(*) from t").Rows()
resBuff := bytes.NewBufferString("")
Expand Down
1 change: 1 addition & 0 deletions planner/core/binary_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func TestBinaryPlanInExplainAndSlowLog(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
// If we don't set this, it will be false sometimes and the cost in the result will be different.
tk.MustExec("set @@tidb_enable_chunk_rpc=true")

Expand Down
1 change: 1 addition & 0 deletions planner/core/cbo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ func TestIssue9562(t *testing.T) {
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
var input [][]string
var output []struct {
SQL []string
Expand Down
31 changes: 18 additions & 13 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ func TestSelPushDownTiFlash(t *testing.T) {

tk.MustExec("set @@session.tidb_isolation_read_engines = 'tiflash'")
tk.MustExec("set @@session.tidb_allow_mpp = 0")
tk.MustExec("set tidb_cost_model_version=2")

var input []string
var output []struct {
Expand Down Expand Up @@ -1937,6 +1938,7 @@ func TestIssue17813(t *testing.T) {
func TestHintWithRequiredProperty(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("set @@session.tidb_executor_concurrency = 4;")
tk.MustExec("set @@session.tidb_hash_join_concurrency = 5;")
tk.MustExec("set @@session.tidb_distsql_scan_concurrency = 15;")
Expand Down Expand Up @@ -2683,6 +2685,7 @@ func TestIndexJoinOnClusteredIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOn
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t (a int, b varchar(20), c decimal(40,10), d int, primary key(a,b), key(c))")
Expand Down Expand Up @@ -5799,6 +5802,7 @@ func TestIssues27130(t *testing.T) {
tk.MustExec("use test")

tk.MustExec("drop table if exists t1")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("create table t1( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a));")
tk.MustQuery(`explain format=brief select * from t1 where a like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
Expand All @@ -5814,14 +5818,14 @@ func TestIssues27130(t *testing.T) {
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t2( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a, b));")
tk.MustQuery(`explain format=brief select * from t2 where a like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"IndexReader 8000.00 root index:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
" └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a, b) keep order:false, stats:pseudo",
))
tk.MustQuery(`explain format=brief select * from t2 where a like "A%" and b like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"IndexReader 8000.00 root index:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92), like(test.t2.b, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
" └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a, b) keep order:false, stats:pseudo",
))

tk.MustExec("drop table if exists t3")
Expand Down Expand Up @@ -6585,6 +6589,7 @@ func TestIssue31240(t *testing.T) {
tk.MustExec("use test")
tk.MustExec("create table t31240(a int, b int);")
tk.MustExec("set @@tidb_allow_mpp = 0")
tk.MustExec("set tidb_cost_model_version=2")

tbl, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t31240", L: "t31240"})
require.NoError(t, err)
Expand Down Expand Up @@ -7114,26 +7119,26 @@ func TestAggWithJsonPushDownToTiFlash(t *testing.T) {
}

rows := [][]interface{}{
{"HashAgg_8", "root", "funcs:avg(Column#4)->Column#3"},
{"HashAgg_6", "root", "funcs:avg(Column#4)->Column#3"},
{"└─Projection_19", "root", "cast(test.t.a, double BINARY)->Column#4"},
{" └─TableReader_14", "root", "data:TableFullScan_13"},
{" └─TableFullScan_13", "cop[tiflash]", "keep order:false, stats:pseudo"},
{" └─TableReader_12", "root", "data:TableFullScan_11"},
{" └─TableFullScan_11", "cop[tiflash]", "keep order:false, stats:pseudo"},
}
tk.MustQuery("explain select avg(a) from t;").CheckAt([]int{0, 2, 4}, rows)

rows = [][]interface{}{
{"HashAgg_8", "root", "funcs:sum(Column#4)->Column#3"},
{"HashAgg_6", "root", "funcs:sum(Column#4)->Column#3"},
{"└─Projection_19", "root", "cast(test.t.a, double BINARY)->Column#4"},
{" └─TableReader_14", "root", "data:TableFullScan_13"},
{" └─TableFullScan_13", "cop[tiflash]", "keep order:false, stats:pseudo"},
{" └─TableReader_12", "root", "data:TableFullScan_11"},
{" └─TableFullScan_11", "cop[tiflash]", "keep order:false, stats:pseudo"},
}
tk.MustQuery("explain select sum(a) from t;").CheckAt([]int{0, 2, 4}, rows)

rows = [][]interface{}{
{"HashAgg_8", "root", "funcs:group_concat(Column#4 separator \",\")->Column#3"},
{"HashAgg_6", "root", "funcs:group_concat(Column#4 separator \",\")->Column#3"},
{"└─Projection_13", "root", "cast(test.t.a, var_string(4294967295))->Column#4"},
{" └─TableReader_12", "root", "data:TableFullScan_11"},
{" └─TableFullScan_11", "cop[tiflash]", "keep order:false, stats:pseudo"},
{" └─TableReader_10", "root", "data:TableFullScan_9"},
{" └─TableFullScan_9", "cop[tiflash]", "keep order:false, stats:pseudo"},
}
tk.MustQuery("explain select /*+ hash_agg() */ group_concat(a) from t;").CheckAt([]int{0, 2, 4}, rows)
}
Expand Down
1 change: 1 addition & 0 deletions planner/core/partition_pruner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestHashPartitionPruner(t *testing.T) {
func TestRangeColumnPartitionPruningForIn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop database if exists test_range_col_in")
tk.MustExec("create database test_range_col_in")
tk.MustExec("use test_range_col_in")
Expand Down
6 changes: 6 additions & 0 deletions planner/core/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func TestDAGPlanBuilderJoin(t *testing.T) {

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
sessionVars := tk.Session().GetSessionVars()
sessionVars.ExecutorConcurrency = 4
sessionVars.SetDistSQLScanConcurrency(15)
Expand Down Expand Up @@ -220,6 +221,7 @@ func TestDAGPlanBuilderSubquery(t *testing.T) {

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by
sessionVars := tk.Session().GetSessionVars()
sessionVars.SetHashAggFinalConcurrency(1)
Expand Down Expand Up @@ -839,6 +841,7 @@ func TestHintScope(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")

var input []string
var output []struct {
Expand Down Expand Up @@ -1325,6 +1328,7 @@ func TestPushdownDistinctEnable(t *testing.T) {
vars := []string{
fmt.Sprintf("set @@session.%s = 1", variable.TiDBOptDistinctAggPushDown),
"set session tidb_opt_agg_push_down = 1",
"set tidb_cost_model_version = 2",
}
doTestPushdownDistinct(t, vars, input, output)
}
Expand Down Expand Up @@ -1362,6 +1366,7 @@ func TestPushdownDistinctEnableAggPushDownDisable(t *testing.T) {
vars := []string{
fmt.Sprintf("set @@session.%s = 1", variable.TiDBOptDistinctAggPushDown),
"set session tidb_opt_agg_push_down = 0",
"set tidb_cost_model_version=2",
}
doTestPushdownDistinct(t, vars, input, output)
}
Expand Down Expand Up @@ -2365,6 +2370,7 @@ func TestMPPSinglePartitionType(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop table if exists employee")
tk.MustExec("create table employee(empid int, deptid int, salary decimal(10,2))")
tk.MustExec("set tidb_enforce_mpp=0")
Expand Down
7 changes: 6 additions & 1 deletion planner/core/plan_cost_ver1.go
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,12 @@ func getCardinality(operator PhysicalPlan, costFlag uint64) float64 {
actualProbeCnt := operator.getActualProbeCnt(operator.SCtx().GetSessionVars().StmtCtx.RuntimeStatsColl)
return getOperatorActRows(operator) / float64(actualProbeCnt)
}
return operator.StatsCount()
rows := operator.StatsCount()
if rows == 0 && operator.SCtx().GetSessionVars().CostModelVersion == modelVer2 {
// 0 est-row can lead to 0 operator cost which makes plan choice unstable.
rows = 1
}
return rows
}

// estimateNetSeekCost calculates the net seek cost for the plan.
Expand Down
Loading