Skip to content

Commit

Permalink
stats: resolve the constant selectivity when handling DNF exprs (ping…
Browse files Browse the repository at this point in the history
  • Loading branch information
AilinKid authored Jan 7, 2022
1 parent 29d0d01 commit 375b71b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
38 changes: 38 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5195,3 +5195,41 @@ func (s *testIntegrationSuite) TestIssue20510(c *C) {
"4 2 <nil> <nil>",
))
}

// TestDNFCondSelectivityWithConst test selectivity calculation with DNF conditions with one is const.
// Close https://github.com/pingcap/tidb/issues/31096
func (s *testIntegrationSuite) TestDNFCondSelectivityWithConst(c *C) {
testKit := testkit.NewTestKit(c, s.store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t1")
testKit.MustExec("create table t1(a int, b int, c int);")
testKit.MustExec("insert into t1 value(10,10,10)")
for i := 0; i < 7; i++ {
testKit.MustExec("insert into t1 select * from t1")
}
testKit.MustExec("insert into t1 value(1,1,1)")
testKit.MustExec("analyze table t1")

testKit.MustQuery("explain select * from t1 where a=1 or b=1;").Check(testkit.Rows("TableReader_7 1.99 root data:Selection_6]\n" +
"[└─Selection_6 1.99 cop[tikv] or(eq(test.t1.a, 1), eq(test.t1.b, 1))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where 0=1 or a=1 or b=1;").Check(testkit.Rows("TableReader_7 1.99 root data:Selection_6]\n" +
"[└─Selection_6 1.99 cop[tikv] or(0, or(eq(test.t1.a, 1), eq(test.t1.b, 1)))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where null or a=1 or b=1;").Check(testkit.Rows("TableReader_7 1.99 root data:Selection_6]\n" +
"[└─Selection_6 1.99 cop[tikv] or(0, or(eq(test.t1.a, 1), eq(test.t1.b, 1)))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where a=1 or false or b=1;").Check(testkit.Rows("TableReader_7 1.99 root data:Selection_6]\n" +
"[└─Selection_6 1.99 cop[tikv] or(eq(test.t1.a, 1), or(0, eq(test.t1.b, 1)))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where a=1 or b=1 or \"false\";").Check(testkit.Rows("TableReader_7 1.99 root data:Selection_6]\n" +
"[└─Selection_6 1.99 cop[tikv] or(eq(test.t1.a, 1), or(eq(test.t1.b, 1), 0))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where 1=1 or a=1 or b=1;").Check(testkit.Rows("TableReader_7 129.00 root data:Selection_6]\n" +
"[└─Selection_6 129.00 cop[tikv] or(1, or(eq(test.t1.a, 1), eq(test.t1.b, 1)))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustQuery("explain select * from t1 where a=1 or b=1 or 1=1;").Check(testkit.Rows("TableReader_7 129.00 root data:Selection_6]\n" +
"[└─Selection_6 129.00 cop[tikv] or(eq(test.t1.a, 1), or(eq(test.t1.b, 1), 1))]\n" +
"[ └─TableFullScan_5 129.00 cop[tikv] table:t1 keep order:false"))
testKit.MustExec("drop table if exists t1")
}
4 changes: 2 additions & 2 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@
{
"SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, b, c) */ * from t where 1 or t.a = 1 or t.b = 2",
"Plan": [
"TableReader 8000.40 root data:Selection",
"└─Selection 8000.40 cop[tikv] or(1, or(eq(test.t.a, 1), eq(test.t.b, 2)))",
"TableReader 10000.00 root data:Selection",
"└─Selection 10000.00 cop[tikv] or(1, or(eq(test.t.a, 1), eq(test.t.b, 2)))",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
}
Expand Down
20 changes: 19 additions & 1 deletion statistics/selectivity.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,24 @@ func (coll *HistColl) Selectivity(ctx sessionctx.Context, exprs []expression.Exp
if ok {
continue
}
// where {"0" / 0 / "false" / false / null} or A or B ... the '0' constant item should be ignored.
if c, ok := cond.(*expression.Constant); ok {
if !expression.MaybeOverOptimized4PlanCache(ctx, []expression.Expression{cond}) {
if c.Value.IsNull() {
// constant is null
continue
}
if isTrue, err := c.Value.ToBool(sc); err == nil {
if isTrue == 0 {
// constant == 0
continue
}
// constant == 1
selectivity = 1.0
break
}
}
}

var cnfItems []expression.Expression
if scalar, ok := cond.(*expression.ScalarFunction); ok && scalar.FuncName.L == ast.LogicAnd {
Expand All @@ -365,7 +383,7 @@ func (coll *HistColl) Selectivity(ctx sessionctx.Context, exprs []expression.Exp
curSelectivity, _, err := coll.Selectivity(ctx, cnfItems, nil)
if err != nil {
logutil.BgLogger().Debug("something wrong happened, use the default selectivity", zap.Error(err))
selectivity = selectionFactor
curSelectivity = selectionFactor
}

selectivity = selectivity + curSelectivity - selectivity*curSelectivity
Expand Down

0 comments on commit 375b71b

Please sign in to comment.