Skip to content

Commit

Permalink
session/statistics: discard feedbacks from delete / update (#17452)…
Browse files Browse the repository at this point in the history
… (#17840)

* cherry pick #17452 to release-2.1

Signed-off-by: sre-bot <sre-bot@pingcap.com>

* resolve conflicts

Co-authored-by: Kenan Yao <cauchy1992@gmail.com>
Co-authored-by: ti-srebot <66930949+ti-srebot@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 22, 2020
1 parent 47e286b commit 10140bb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 10 deletions.
17 changes: 13 additions & 4 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1797,7 +1797,10 @@ func buildNoRangeTableReader(b *executorBuilder, v *plannercore.PhysicalTableRea
} else {
e.feedback = statistics.NewQueryFeedback(e.physicalTableID, ts.Hist, int64(ts.StatsCount()), ts.Desc)
}
collect := e.feedback.CollectFeedback(len(ts.Ranges))
collect := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(ts.Ranges))
if !collect {
e.feedback.Invalidate()
}
e.dagPB.CollectRangeCounts = &collect

for i := range v.Schema().Columns {
Expand Down Expand Up @@ -1854,7 +1857,10 @@ func buildNoRangeIndexReader(b *executorBuilder, v *plannercore.PhysicalIndexRea
} else {
e.feedback = statistics.NewQueryFeedback(e.physicalTableID, is.Hist, int64(is.StatsCount()), is.Desc)
}
collect := e.feedback.CollectFeedback(len(is.Ranges))
collect := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(is.Ranges))
if !collect {
e.feedback.Invalidate()
}
e.dagPB.CollectRangeCounts = &collect

for _, col := range v.OutputColumns {
Expand Down Expand Up @@ -1928,10 +1934,13 @@ func buildNoRangeIndexLookUpReader(b *executorBuilder, v *plannercore.PhysicalIn
} else {
e.feedback = statistics.NewQueryFeedback(e.physicalTableID, is.Hist, int64(is.StatsCount()), is.Desc)
}
// do not collect the feedback for table request.
// Do not collect the feedback for table request.
collectTable := false
e.tableRequest.CollectRangeCounts = &collectTable
collectIndex := e.feedback.CollectFeedback(len(is.Ranges))
collectIndex := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(is.Ranges))
if !collectIndex {
e.feedback.Invalidate()
}
e.dagPB.CollectRangeCounts = &collectIndex
if cols, ok := v.Schema().TblID2Handle[is.Table.ID]; ok {
e.handleIdx = cols[0].Index
Expand Down
14 changes: 8 additions & 6 deletions statistics/feedback.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,18 @@ var (
)

// CollectFeedback decides whether to collect the feedback. It returns false when:
// 1: the histogram is nil or has no buckets;
// 2: the number of scan ranges exceeds the limit because it may affect the performance;
// 3: it does not pass the probabilistic sampler.
func (q *QueryFeedback) CollectFeedback(numOfRanges int) bool {
// 1: the feedback is not generated by select query;
// 2: the histogram is nil or has no buckets;
// 3: the number of scan ranges exceeds the limit because it may affect the performance;
// 4: it does not pass the probabilistic sampler.
func CollectFeedback(sc *stmtctx.StatementContext, q *QueryFeedback, numOfRanges int) bool {
if !sc.InSelectStmt {
return false
}
if q.hist == nil || q.hist.Len() == 0 {
q.Invalidate()
return false
}
if numOfRanges > MaxNumberOfRanges || rand.Float64() > FeedbackProbability {
q.Invalidate()
return false
}
return true
Expand Down
30 changes: 30 additions & 0 deletions statistics/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1445,3 +1445,33 @@ func (s *testStatsUpdateSuite) TestUnsignedFeedbackRanges(c *C) {
c.Assert(tbl.Columns[1].ToString(0), Equals, tests[i].hist)
}
}

func (s *testStatsUpdateSuite) TestDeleteUpdateFeedback(c *C) {
defer cleanEnv(c, s.store, s.do)
testKit := testkit.NewTestKit(c, s.store)

oriProbability := statistics.FeedbackProbability
defer func() {
statistics.FeedbackProbability = oriProbability
}()
statistics.FeedbackProbability = 1

h := s.do.StatsHandle()
testKit.MustExec("use test")
testKit.MustExec("create table t (a bigint(64), b bigint(64), index idx_ab(a,b))")
for i := 0; i < 20; i++ {
testKit.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i/5, i))
}
c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil)
testKit.MustExec("analyze table t with 3 buckets")

testKit.MustExec("delete from t where a = 1")
c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil)
c.Assert(len(h.GetQueryFeedback()), Equals, 0)
testKit.MustExec("update t set a = 6 where a = 2")
c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil)
c.Assert(len(h.GetQueryFeedback()), Equals, 0)
testKit.MustExec("explain analyze delete from t where a = 3")
c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil)
c.Assert(len(h.GetQueryFeedback()), Equals, 0)
}

0 comments on commit 10140bb

Please sign in to comment.