diff --git a/executor/builder.go b/executor/builder.go index 96298f6350a3a..8d23dbd3c68ff 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -1864,7 +1864,7 @@ func buildNoRangeTableReader(b *executorBuilder, v *plannercore.PhysicalTableRea } else { e.feedback = statistics.NewQueryFeedback(getPhysicalTableID(tbl), ts.Hist, int64(ts.StatsCount()), ts.Desc) } - collect := (b.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil) || e.feedback.CollectFeedback(len(ts.Ranges)) + collect := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(ts.Ranges)) if !collect { e.feedback.Invalidate() } @@ -1929,7 +1929,7 @@ func buildNoRangeIndexReader(b *executorBuilder, v *plannercore.PhysicalIndexRea } else { e.feedback = statistics.NewQueryFeedback(e.physicalTableID, is.Hist, int64(is.StatsCount()), is.Desc) } - collect := (b.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil) || e.feedback.CollectFeedback(len(is.Ranges)) + collect := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(is.Ranges)) if !collect { e.feedback.Invalidate() } @@ -2005,10 +2005,10 @@ func buildNoRangeIndexLookUpReader(b *executorBuilder, v *plannercore.PhysicalIn } else { e.feedback = statistics.NewQueryFeedback(getPhysicalTableID(tbl), 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 := (b.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil) || e.feedback.CollectFeedback(len(is.Ranges)) + collectIndex := statistics.CollectFeedback(b.ctx.GetSessionVars().StmtCtx, e.feedback, len(is.Ranges)) if !collectIndex { e.feedback.Invalidate() } diff --git a/statistics/feedback.go b/statistics/feedback.go index 89e5b3c540924..0df0d8de36ee4 100644 --- a/statistics/feedback.go +++ b/statistics/feedback.go @@ -99,10 +99,14 @@ func (q *QueryFeedback) CalcErrorRate() float64 { } // 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 { return false } diff --git a/statistics/handle/update_test.go b/statistics/handle/update_test.go index 21258e1be004c..fefb6be4f6249 100644 --- a/statistics/handle/update_test.go +++ b/statistics/handle/update_test.go @@ -1672,3 +1672,33 @@ func (s *testStatsSuite) TestLoadHistCorrelation(c *C) { c.Assert(len(result.Rows()), Equals, 1) c.Assert(result.Rows()[0][9], Equals, "1") } + +func (s *testStatsSuite) 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.Store(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(handle.DumpAll), IsNil) + testKit.MustExec("analyze table t with 3 buckets") + + testKit.MustExec("delete from t where a = 1") + c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil) + c.Assert(len(h.GetQueryFeedback()), Equals, 0) + testKit.MustExec("update t set a = 6 where a = 2") + c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil) + c.Assert(len(h.GetQueryFeedback()), Equals, 0) + testKit.MustExec("explain analyze delete from t where a = 3") + c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil) + c.Assert(len(h.GetQueryFeedback()), Equals, 0) +}