Skip to content

Commit

Permalink
Planner: Do not allow cardinality to go below 1 (#55242)
Browse files Browse the repository at this point in the history
close #47400
  • Loading branch information
terry1purcell committed Aug 20, 2024
1 parent adc7597 commit f2c278d
Show file tree
Hide file tree
Showing 30 changed files with 391 additions and 354 deletions.
1 change: 1 addition & 0 deletions pkg/planner/cardinality/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ go_library(
"//pkg/planner/property",
"//pkg/planner/util",
"//pkg/planner/util/debugtrace",
"//pkg/planner/util/fixcontrol",
"//pkg/sessionctx/stmtctx",
"//pkg/statistics",
"//pkg/tablecodec",
Expand Down
13 changes: 12 additions & 1 deletion pkg/planner/cardinality/row_count_column.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/pingcap/errors"
"github.com/pingcap/tidb/pkg/planner/context"
"github.com/pingcap/tidb/pkg/planner/util/debugtrace"
"github.com/pingcap/tidb/pkg/planner/util/fixcontrol"
"github.com/pingcap/tidb/pkg/statistics"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util/codec"
Expand Down Expand Up @@ -312,7 +313,17 @@ func GetColumnRowCount(sctx context.PlanContext, c *statistics.Column, ranges []
}
rowCount += cnt
}
rowCount = mathutil.Clamp(rowCount, 0, float64(realtimeRowCount))
allowZeroEst := fixcontrol.GetBoolWithDefault(
sctx.GetSessionVars().GetOptimizerFixControlMap(),
fixcontrol.Fix47400,
false,
)
if allowZeroEst {
rowCount = mathutil.Clamp(rowCount, 0, float64(realtimeRowCount))
} else {
// Don't allow the final result to go below 1 row
rowCount = mathutil.Clamp(rowCount, 1, float64(realtimeRowCount))
}
return rowCount, nil
}

Expand Down
13 changes: 12 additions & 1 deletion pkg/planner/cardinality/row_count_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/pingcap/tidb/pkg/kv"
"github.com/pingcap/tidb/pkg/planner/context"
"github.com/pingcap/tidb/pkg/planner/util/debugtrace"
"github.com/pingcap/tidb/pkg/planner/util/fixcontrol"
"github.com/pingcap/tidb/pkg/sessionctx/stmtctx"
"github.com/pingcap/tidb/pkg/statistics"
"github.com/pingcap/tidb/pkg/types"
Expand Down Expand Up @@ -350,7 +351,17 @@ func getIndexRowCountForStatsV2(sctx context.PlanContext, idx *statistics.Index,
}
totalCount += count
}
totalCount = mathutil.Clamp(totalCount, 0, float64(realtimeRowCount))
allowZeroEst := fixcontrol.GetBoolWithDefault(
sctx.GetSessionVars().GetOptimizerFixControlMap(),
fixcontrol.Fix47400,
false,
)
if allowZeroEst {
totalCount = mathutil.Clamp(totalCount, 0, float64(realtimeRowCount))
} else {
// Don't allow the final result to go below 1 row
totalCount = mathutil.Clamp(totalCount, 1, float64(realtimeRowCount))
}
return totalCount, nil
}

Expand Down
20 changes: 10 additions & 10 deletions pkg/planner/cardinality/selectivity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestEstimationForUnknownValues(t *testing.T) {
colID := table.Meta().Columns[0].ID
count, err := cardinality.GetRowCountByColumnRanges(sctx, &statsTbl.HistColl, colID, getRange(30, 30))
require.NoError(t, err)
require.Equal(t, 0.2, count)
require.Equal(t, 1.0, count)

count, err = cardinality.GetRowCountByColumnRanges(sctx, &statsTbl.HistColl, colID, getRange(9, 30))
require.NoError(t, err)
Expand Down Expand Up @@ -265,7 +265,7 @@ func TestEstimationForUnknownValues(t *testing.T) {
colID = table.Meta().Columns[0].ID
count, err = cardinality.GetRowCountByColumnRanges(sctx, &statsTbl.HistColl, colID, getRange(1, 30))
require.NoError(t, err)
require.Equal(t, 0.0, count)
require.Equal(t, 1.0, count)

testKit.MustExec("drop table t")
testKit.MustExec("create table t(a int, b int, index idx(b))")
Expand All @@ -278,7 +278,7 @@ func TestEstimationForUnknownValues(t *testing.T) {
colID = table.Meta().Columns[0].ID
count, err = cardinality.GetRowCountByColumnRanges(sctx, &statsTbl.HistColl, colID, getRange(2, 2))
require.NoError(t, err)
require.Equal(t, 0.0, count)
require.Equal(t, 1.0, count)

idxID = table.Meta().Indices[0].ID
count, err = cardinality.GetRowCountByIndexRanges(sctx, &statsTbl.HistColl, idxID, getRange(2, 2))
Expand Down Expand Up @@ -402,8 +402,8 @@ func TestSelectivity(t *testing.T) {
},
{
exprs: "a >= 1 and b > 1 and a < 2",
selectivity: 0.01783264746,
selectivityAfterIncrease: 0.01851851852,
selectivity: 0.017832647462277088,
selectivityAfterIncrease: 0.018518518518518517,
},
{
exprs: "a >= 1 and c > 1 and a < 2",
Expand All @@ -422,13 +422,13 @@ func TestSelectivity(t *testing.T) {
},
{
exprs: "b > 1",
selectivity: 0.96296296296,
selectivity: 0.9629629629629629,
selectivityAfterIncrease: 1,
},
{
exprs: "a > 1 and b < 2 and c > 3 and d < 4 and e > 5",
selectivity: 0,
selectivityAfterIncrease: 0,
selectivity: 5.870830440255832e-05,
selectivityAfterIncrease: 1.51329827770157e-05,
},
{
exprs: longExpr,
Expand Down Expand Up @@ -1190,8 +1190,8 @@ func TestCrossValidationSelectivity(t *testing.T) {
require.NoError(t, h.DumpStatsDeltaToKV(true))
tk.MustExec("analyze table t")
tk.MustQuery("explain format = 'brief' select * from t where a = 1 and b > 0 and b < 1000 and c > 1000").Check(testkit.Rows(
"TableReader 0.00 root data:Selection",
"└─Selection 0.00 cop[tikv] gt(test.t.c, 1000)",
"TableReader 1.00 root data:Selection",
"└─Selection 1.00 cop[tikv] gt(test.t.c, 1000)",
" └─TableRangeScan 2.00 cop[tikv] table:t range:(1 0,1 1000), keep order:false"))
}

Expand Down
22 changes: 11 additions & 11 deletions pkg/planner/cardinality/testdata/cardinality_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
{
"Start": 800,
"End": 900,
"Count": 755.754166655054
"Count": 791.004166655054
},
{
"Start": 900,
Expand Down Expand Up @@ -79,7 +79,7 @@
{
"Start": 800,
"End": 1000,
"Count": 1213.946869573942
"Count": 1249.196869573942
},
{
"Start": 900,
Expand All @@ -104,7 +104,7 @@
{
"Start": 200,
"End": 400,
"Count": 1215.0288209899081
"Count": 1188.7788209899081
},
{
"Start": 200,
Expand Down Expand Up @@ -2589,7 +2589,7 @@
},
{
"Name": "a",
"Result": 0
"Result": 1
}
]
},
Expand Down Expand Up @@ -2887,15 +2887,15 @@
},
{
"End estimate range": {
"RowCount": 0,
"RowCount": 1,
"Type": "Range"
}
}
]
},
{
"Name": "iab",
"Result": 0
"Result": 1
}
]
},
Expand Down Expand Up @@ -3447,11 +3447,11 @@
"Expressions": [
"lt(test.t.a, -1500)"
],
"Selectivity": 0,
"Selectivity": 0.0003246753246753247,
"partial cover": false
},
{
"Result": 0
"Result": 2.1082813290605499e-7
}
]
}
Expand Down Expand Up @@ -3940,7 +3940,7 @@
},
{
"Name": "iab",
"Result": 0
"Result": 1
}
]
},
Expand Down Expand Up @@ -4093,11 +4093,11 @@
"Expressions": [
"lt(test.t.a, -1500)"
],
"Selectivity": 0,
"Selectivity": 0.0003246753246753247,
"partial cover": false
},
{
"Result": 0
"Result": 1.9066503965832828e-7
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,13 @@
"└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t keep order:false"
],
[
"TableReader 0.00 root data:Selection",
"└─Selection 0.00 cop[tikv] eq(test.t.b, 1)",
"TableReader 1.00 root data:Selection",
"└─Selection 1.00 cop[tikv] eq(test.t.b, 1)",
" └─TableFullScan 2.00 cop[tikv] table:t keep order:false"
],
[
"TableReader 0.00 root data:Selection",
"└─Selection 0.00 cop[tikv] lt(test.t.b, 1)",
"TableReader 1.00 root data:Selection",
"└─Selection 1.00 cop[tikv] lt(test.t.b, 1)",
" └─TableFullScan 2.00 cop[tikv] table:t keep order:false"
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@
"└─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false"
],
"StaticPlan": [
"PartitionUnion 1.00 root ",
"PartitionUnion 3.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[1,1], keep order:false",
"├─IndexReader 1.00 root index:IndexRangeScan",
Expand All @@ -725,7 +725,7 @@
"└─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[2,2], keep order:false"
],
"StaticPlan": [
"PartitionUnion 1.00 root ",
"PartitionUnion 3.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[2,2], keep order:false",
"├─IndexReader 1.00 root index:IndexRangeScan",
Expand All @@ -741,7 +741,7 @@
"└─IndexRangeScan 2.00 cop[tikv] table:t, index:b(b) range:[1,2], keep order:false"
],
"StaticPlan": [
"PartitionUnion 2.00 root ",
"PartitionUnion 3.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[1,2], keep order:false",
"├─IndexReader 1.00 root index:IndexRangeScan",
Expand All @@ -757,7 +757,7 @@
"└─IndexRangeScan 2.00 cop[tikv] table:t, index:b(b) range:[2,2], [3,3], [4,4], keep order:false"
],
"StaticPlan": [
"PartitionUnion 2.00 root ",
"PartitionUnion 3.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[2,2], [3,3], [4,4], keep order:false",
"├─IndexReader 1.00 root index:IndexRangeScan",
Expand All @@ -773,7 +773,7 @@
"└─IndexRangeScan 2.00 cop[tikv] table:t, index:b(b) range:[2,2], [3,3], keep order:false"
],
"StaticPlan": [
"PartitionUnion 2.00 root ",
"PartitionUnion 3.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[2,2], [3,3], keep order:false",
"├─IndexReader 1.00 root index:IndexRangeScan",
Expand Down Expand Up @@ -854,7 +854,7 @@
"└─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false"
],
"StaticPlan": [
"PartitionUnion 1.00 root ",
"PartitionUnion 2.00 root ",
"├─IndexReader 1.00 root index:IndexRangeScan",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, partition:P0, index:b(b) range:[1,1], keep order:false",
"└─IndexReader 1.00 root index:IndexRangeScan",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@
{
"Query": "explain format = brief select * from t join tp where tp.a = 10 and t.b = tp.c",
"Result": [
"Projection 0.00 root test.t.a, test.t.b, test.t.c, test.tp.a, test.tp.b, test.tp.c",
"└─HashJoin 0.00 root inner join, equal:[eq(test.tp.c, test.t.b)]",
" ├─TableReader(Build) 0.00 root partition:p1 data:Selection",
" │ └─Selection 0.00 cop[tikv] eq(test.tp.a, 10), not(isnull(test.tp.c))",
"Projection 1.00 root test.t.a, test.t.b, test.t.c, test.tp.a, test.tp.b, test.tp.c",
"└─HashJoin 1.00 root inner join, equal:[eq(test.tp.c, test.t.b)]",
" ├─TableReader(Build) 1.00 root partition:p1 data:Selection",
" │ └─Selection 1.00 cop[tikv] eq(test.tp.a, 10), not(isnull(test.tp.c))",
" │ └─TableFullScan 6.00 cop[tikv] table:tp keep order:false, stats:partial[c:allEvicted]",
" └─TableReader(Probe) 3.00 root data:Selection",
" └─Selection 3.00 cop[tikv] not(isnull(test.t.b))",
Expand Down
14 changes: 7 additions & 7 deletions pkg/planner/core/casetest/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,25 @@
"SQL": "explain format = 'verbose' select count(*) from t3 where b = 0",
"Plan": [
"StreamAgg_10 1.00 64.98 root funcs:count(1)->Column#4",
"└─IndexReader_15 0.00 15.08 root index:IndexRangeScan_14",
" └─IndexRangeScan_14 0.00 162.80 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false"
"└─IndexReader_15 1.00 15.08 root index:IndexRangeScan_14",
" └─IndexRangeScan_14 1.00 162.80 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false"
]
},
{
"SQL": "explain format = 'verbose' select /*+ use_index(t3, c) */ count(a) from t3 where b = 0",
"Plan": [
"StreamAgg_10 1.00 2001.63 root funcs:count(test.t3.a)->Column#4",
"└─IndexLookUp_17 0.00 1951.73 root ",
" ├─IndexRangeScan_15(Build) 0.00 203.50 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false",
" └─TableRowIDScan_16(Probe) 0.00 227.31 cop[tikv] table:t3 keep order:false"
"└─IndexLookUp_17 1.00 1951.73 root ",
" ├─IndexRangeScan_15(Build) 1.00 203.50 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false",
" └─TableRowIDScan_16(Probe) 1.00 227.31 cop[tikv] table:t3 keep order:false"
]
},
{
"SQL": "explain format = 'verbose' select count(*) from t2 where a = 0",
"Plan": [
"StreamAgg_12 1.00 109.57 root funcs:count(1)->Column#4",
"└─TableReader_20 0.00 59.67 root data:Selection_19",
" └─Selection_19 0.00 831.62 cop[tikv] eq(test.t2.a, 0)",
"└─TableReader_20 1.00 59.67 root data:Selection_19",
" └─Selection_19 1.00 831.62 cop[tikv] eq(test.t2.a, 0)",
" └─TableFullScan_18 3.00 681.92 cop[tikv] table:t2 keep order:false"
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,8 @@
"Plan": [
" TableReader root ",
" └─ExchangeSender cop[tiflash] ",
" └─Selection cop[tiflash] gt(test.t1.b, ?), gt(test.t1.c, ?), or(gt(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, ?), gt(test.t1.c, ?), or(gt(test.t1.a, ?), lt(test.t1.b, ?))",
" └─TableFullScan cop[tiflash] table:t1, range:[?,?], pushed down filter:gt(test.t1.b, ?), keep order:false"
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions pkg/planner/core/testdata/index_merge_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
{
"SQL": "select * from vh",
"Plan": [
"PartitionUnion 0.50 root ",
"PartitionUnion 1.50 root ",
"├─IndexMerge 0.50 root type: intersection",
"│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false",
"│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false",
Expand All @@ -276,7 +276,7 @@
{
"SQL": "select /*+ qb_name(v, v), use_index_merge(@v t1, ia, ibc, id) */ * from v",
"Plan": [
"PartitionUnion 0.50 root ",
"PartitionUnion 1.50 root ",
"├─IndexMerge 0.50 root type: intersection",
"│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false",
"│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false",
Expand All @@ -300,7 +300,7 @@
{
"SQL": "select /*+ qb_name(v, v@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v",
"Plan": [
"PartitionUnion 0.50 root ",
"PartitionUnion 1.50 root ",
"├─IndexMerge 0.50 root type: intersection",
"│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false",
"│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false",
Expand All @@ -324,7 +324,7 @@
{
"SQL": "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v",
"Plan": [
"PartitionUnion 0.50 root ",
"PartitionUnion 1.50 root ",
"├─IndexMerge 0.50 root type: intersection",
"│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false",
"│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false",
Expand All @@ -348,7 +348,7 @@
{
"SQL": "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v",
"Plan": [
"PartitionUnion 0.50 root ",
"PartitionUnion 1.50 root ",
"├─IndexMerge 0.50 root type: intersection",
"│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false",
"│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false",
Expand Down
Loading

0 comments on commit f2c278d

Please sign in to comment.