From 99dc72385244a38dbd1b8b880a3093d6cb8f00bd Mon Sep 17 00:00:00 2001 From: pingcap-github-bot Date: Fri, 19 Jun 2020 18:14:29 +0800 Subject: [PATCH] session/statistics: discard feedbacks from `delete ... (#17452) (#17843) --- executor/builder.go | 8 ++++---- statistics/feedback.go | 12 ++++++++---- statistics/handle/update_test.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/executor/builder.go b/executor/builder.go index f4d15fafceb32..341ee5f7ebafa 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -2274,7 +2274,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() } @@ -2357,7 +2357,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() } @@ -2460,10 +2460,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 9773fd206d6d8..974cf121f3000 100644 --- a/statistics/feedback.go +++ b/statistics/feedback.go @@ -98,10 +98,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 8109f932bd801..6bd2139afc35c 100644 --- a/statistics/handle/update_test.go +++ b/statistics/handle/update_test.go @@ -1674,3 +1674,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) +}