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: Do not allow cardinality to go below 1 | tidb-test=pr/2376 (#55242) #59074

Closed
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
5 changes: 5 additions & 0 deletions cmd/explaintest/r/explain_easy.result
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,13 @@ insert into t values (1),(2),(2),(2),(9),(9),(9),(10);
analyze table t with 1 buckets;
explain format = 'brief' select * from t where a >= 3 and a <= 8;
id estRows task access object operator info
<<<<<<< HEAD:cmd/explaintest/r/explain_easy.result
TableReader 0.00 root data:Selection
└─Selection 0.00 cop[tikv] ge(test.t.a, 3), le(test.t.a, 8)
=======
TableReader 1.00 root data:Selection
└─Selection 1.00 cop[tikv] ge(explain_easy.t.a, 3), le(explain_easy.t.a, 8)
>>>>>>> f2c278ddc6b (Planner: Do not allow cardinality to go below 1 (#55242)):tests/integrationtest/r/explain_easy.result
└─TableFullScan 8.00 cop[tikv] table:t keep order:false
drop table t;
create table t(a int, b int, index idx_ab(a, b));
Expand Down
7 changes: 7 additions & 0 deletions cmd/explaintest/r/explain_generate_column_substitute.result
Original file line number Diff line number Diff line change
Expand Up @@ -440,10 +440,17 @@ Projection 1.00 root test.t.a, test.t.b
└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t keep order:false
desc format = 'brief' select * from t where not (lower(b) >= "a");
id estRows task access object operator info
<<<<<<< HEAD:cmd/explaintest/r/explain_generate_column_substitute.result
Projection 0.00 root test.t.a, test.t.b
└─IndexLookUp 0.00 root
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:expression_index(lower(`b`), `a` + 1) range:[-inf,"a"), keep order:false
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false
=======
Projection 1.00 root explain_generate_column_substitute.t.a, explain_generate_column_substitute.t.b
└─IndexLookUp 1.00 root
├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:expression_index(lower(`b`), `a` + 1) range:[-inf,"a"), keep order:false
└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t keep order:false
>>>>>>> f2c278ddc6b (Planner: Do not allow cardinality to go below 1 (#55242)):tests/integrationtest/r/explain_generate_column_substitute.result
desc format = 'brief' select count(upper(b)) from t group by upper(b);
id estRows task access object operator info
StreamAgg 4.80 root group by:upper(test.t.b), funcs:count(upper(test.t.b))->Column#7
Expand Down
48 changes: 24 additions & 24 deletions cmd/explaintest/r/imdbload.result
Original file line number Diff line number Diff line change
Expand Up @@ -287,48 +287,48 @@ IndexLookUp_7 1005030.94 root
└─TableRowIDScan_6(Probe) 1005030.94 cop[tikv] table:char_name keep order:false
trace plan target = 'estimation' select * from char_name where ((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436'));
CE_trace
[{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'I'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'L'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436'))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`or`(`and`(`eq`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.surname_pcode, 'E436')), `and`(`eq`(imdbload.char_name.imdb_index, 'L'), `lt`(imdbload.char_name.surname_pcode, 'E436')))","row_count":804024}]
[{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'I'))","row_count":1},{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'L'))","row_count":1},{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436'))","row_count":2},{"table_name":"char_name","type":"Index Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`or`(`and`(`eq`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.surname_pcode, 'E436')), `and`(`eq`(imdbload.char_name.imdb_index, 'L'), `lt`(imdbload.char_name.surname_pcode, 'E436')))","row_count":804024}]

explain select * from char_name where ((imdb_index = 'V') and (surname_pcode < 'L3416'));
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:["V" -inf,"V" "L3416"), keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:char_name keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:["V" -inf,"V" "L3416"), keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:char_name keep order:false
explain select * from char_name where imdb_index > 'V';
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("V",+inf], keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:char_name keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("V",+inf], keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:char_name keep order:false
trace plan target = 'estimation' select * from char_name where imdb_index > 'V';
CE_trace
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'V' and true))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'V' and true))","row_count":0},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.char_name.imdb_index, 'V')","row_count":0}]
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'V' and true))","row_count":1},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'V' and true))","row_count":1},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.char_name.imdb_index, 'V')","row_count":1}]

explain select * from movie_companies where company_type_id > 2;
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:movie_companies, index:movie_companies_idx_ctypeid(company_type_id) range:(2,+inf], keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:movie_companies keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:movie_companies, index:movie_companies_idx_ctypeid(company_type_id) range:(2,+inf], keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:movie_companies keep order:false
trace plan target = 'estimation' select * from movie_companies where company_type_id > 2;
CE_trace
[{"table_name":"movie_companies","type":"Column Stats-Range","expr":"((company_type_id > 2 and true))","row_count":0},{"table_name":"movie_companies","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4958296},{"table_name":"movie_companies","type":"Index Stats-Range","expr":"((company_type_id > 2 and true))","row_count":0},{"table_name":"movie_companies","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.movie_companies.company_type_id, 2)","row_count":0}]
[{"table_name":"movie_companies","type":"Column Stats-Range","expr":"((company_type_id > 2 and true))","row_count":1},{"table_name":"movie_companies","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4958296},{"table_name":"movie_companies","type":"Index Stats-Range","expr":"((company_type_id > 2 and true))","row_count":1},{"table_name":"movie_companies","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.movie_companies.company_type_id, 2)","row_count":1}]

explain select * from char_name where imdb_index > 'I' and imdb_index < 'II';
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("I","II"), keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:char_name keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("I","II"), keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:char_name keep order:false
trace plan target = 'estimation' select * from char_name where imdb_index > 'I' and imdb_index < 'II';
CE_trace
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'I' and imdb_index < 'II'))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'I' and imdb_index < 'II'))","row_count":0},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`and`(`gt`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.imdb_index, 'II'))","row_count":0}]
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'I' and imdb_index < 'II'))","row_count":1},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'I' and imdb_index < 'II'))","row_count":1},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`and`(`gt`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.imdb_index, 'II'))","row_count":1}]

explain select * from char_name where imdb_index > 'I';
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("I",+inf], keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:char_name keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:char_name, index:itest2(imdb_index, surname_pcode, name_pcode_nf) range:("I",+inf], keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:char_name keep order:false
trace plan target = 'estimation' select * from char_name where imdb_index > 'I';
CE_trace
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'I' and true))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'I' and true))","row_count":0},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.char_name.imdb_index, 'I')","row_count":0}]
[{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((imdb_index > 'I' and true))","row_count":1},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index > 'I' and true))","row_count":1},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.char_name.imdb_index, 'I')","row_count":1}]

explain select * from cast_info where nr_order < -2068070866;
id estRows task access object operator info
Expand All @@ -342,12 +342,12 @@ IndexLookUp_10 34260.33 root
└─TableRowIDScan_9(Probe) 34260.33 cop[tikv] table:aka_title keep order:false
explain select * from aka_title where kind_id > 7;
id estRows task access object operator info
IndexLookUp_10 0.00 root
├─IndexRangeScan_8(Build) 0.00 cop[tikv] table:aka_title, index:aka_title_idx_kindid(kind_id) range:(7,+inf], keep order:false
└─TableRowIDScan_9(Probe) 0.00 cop[tikv] table:aka_title keep order:false
IndexLookUp_10 1.00 root
├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:aka_title, index:aka_title_idx_kindid(kind_id) range:(7,+inf], keep order:false
└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:aka_title keep order:false
trace plan target = 'estimation' select * from aka_title where kind_id > 7;
CE_trace
[{"table_name":"aka_title","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":528337},{"table_name":"aka_title","type":"Column Stats-Range","expr":"((kind_id > 7 and true))","row_count":0},{"table_name":"aka_title","type":"Index Stats-Range","expr":"((kind_id > 7 and true))","row_count":0},{"table_name":"aka_title","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.aka_title.kind_id, 7)","row_count":0}]
[{"table_name":"aka_title","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":528337},{"table_name":"aka_title","type":"Column Stats-Range","expr":"((kind_id > 7 and true))","row_count":1},{"table_name":"aka_title","type":"Index Stats-Range","expr":"((kind_id > 7 and true))","row_count":1},{"table_name":"aka_title","type":"Table Stats-Expression-CNF","expr":"`gt`(imdbload.aka_title.kind_id, 7)","row_count":1}]

explain select * from keyword where ((phonetic_code = 'R1652') and (keyword > 'ecg-monitor' and keyword < 'killers'));
id estRows task access object operator info
Expand Down
10 changes: 10 additions & 0 deletions cmd/explaintest/r/tpch.result
Original file line number Diff line number Diff line change
Expand Up @@ -1298,11 +1298,21 @@ cntrycode;
id estRows task access object operator info
Sort 1.00 root Column#31
└─Projection 1.00 root Column#31, Column#32, Column#33
<<<<<<< HEAD:cmd/explaintest/r/tpch.result
└─HashAgg 1.00 root group by:Column#37, funcs:count(1)->Column#32, funcs:sum(Column#35)->Column#33, funcs:firstrow(Column#36)->Column#31
└─Projection 0.00 root tpch.customer.c_acctbal, substring(tpch.customer.c_phone, 1, 2)->Column#36, substring(tpch.customer.c_phone, 1, 2)->Column#37
└─HashJoin 0.00 root anti semi join, equal:[eq(tpch.customer.c_custkey, tpch.orders.o_custkey)]
├─TableReader(Build) 75000000.00 root data:TableFullScan
│ └─TableFullScan 75000000.00 cop[tikv] table:orders keep order:false
└─TableReader(Probe) 0.00 root data:Selection
└─Selection 0.00 cop[tikv] gt(tpch.customer.c_acctbal, NULL), in(substring(tpch.customer.c_phone, 1, 2), "20", "40", "22", "30", "39", "42", "21")
=======
└─HashAgg 1.00 root group by:Column#36, funcs:count(1)->Column#32, funcs:sum(Column#35)->Column#33, funcs:firstrow(Column#36)->Column#31
└─Projection 0.64 root tpch50.customer.c_acctbal->Column#35, substring(tpch50.customer.c_phone, 1, 2)->Column#36
└─HashJoin 0.64 root anti semi join, equal:[eq(tpch50.customer.c_custkey, tpch50.orders.o_custkey)]
├─TableReader(Build) 75000000.00 root data:TableFullScan
│ └─TableFullScan 75000000.00 cop[tikv] table:orders keep order:false
└─TableReader(Probe) 0.80 root data:Selection
└─Selection 0.80 cop[tikv] gt(tpch50.customer.c_acctbal, NULL), in(substring(tpch50.customer.c_phone, 1, 2), "20", "40", "22", "30", "39", "42", "21")
>>>>>>> f2c278ddc6b (Planner: Do not allow cardinality to go below 1 (#55242)):tests/integrationtest/r/tpch.result
└─TableFullScan 7500000.00 cop[tikv] table:customer keep order:false
95 changes: 95 additions & 0 deletions pkg/planner/cardinality/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "cardinality",
srcs = [
"cross_estimation.go",
"join.go",
"ndv.go",
"pseudo.go",
"row_count_column.go",
"row_count_index.go",
"row_size.go",
"selectivity.go",
"trace.go",
],
importpath = "github.com/pingcap/tidb/pkg/planner/cardinality",
visibility = ["//visibility:public"],
deps = [
"//pkg/expression",
"//pkg/kv",
"//pkg/parser/ast",
"//pkg/parser/format",
"//pkg/parser/model",
"//pkg/parser/mysql",
"//pkg/planner/context",
"//pkg/planner/property",
"//pkg/planner/util",
"//pkg/planner/util/debugtrace",
"//pkg/planner/util/fixcontrol",
"//pkg/sessionctx/stmtctx",
"//pkg/statistics",
"//pkg/tablecodec",
"//pkg/types",
"//pkg/types/parser_driver",
"//pkg/util/chunk",
"//pkg/util/codec",
"//pkg/util/collate",
"//pkg/util/logutil",
"//pkg/util/mathutil",
"//pkg/util/ranger",
"//pkg/util/set",
"//pkg/util/tracing",
"@com_github_pingcap_errors//:errors",
"@com_github_pingcap_failpoint//:failpoint",
"@org_uber_go_zap//:zap",
],
)

go_test(
name = "cardinality_test",
timeout = "short",
srcs = [
"main_test.go",
"row_count_test.go",
"row_size_test.go",
"selectivity_test.go",
"trace_test.go",
],
data = glob(["testdata/**"]),
embed = [":cardinality"],
flaky = True,
shard_count = 28,
deps = [
"//pkg/config",
"//pkg/domain",
"//pkg/executor",
"//pkg/expression",
"//pkg/infoschema",
"//pkg/kv",
"//pkg/parser",
"//pkg/parser/model",
"//pkg/parser/mysql",
"//pkg/planner/core",
"//pkg/planner/core/base",
"//pkg/planner/core/operator/logicalop",
"//pkg/session",
"//pkg/sessionctx",
"//pkg/sessionctx/stmtctx",
"//pkg/sessionctx/variable",
"//pkg/statistics",
"//pkg/testkit",
"//pkg/testkit/testdata",
"//pkg/testkit/testmain",
"//pkg/testkit/testsetup",
"//pkg/types",
"//pkg/util/codec",
"//pkg/util/collate",
"//pkg/util/mock",
"//pkg/util/ranger",
"//pkg/util/tracing",
"@com_github_pingcap_failpoint//:failpoint",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",
],
)
Loading
Loading