diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index 8c5f1d08a4013..23b2de4333af8 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -906,13 +906,39 @@ func (s *testSerialStatsSuite) prepareForGlobalStatsWithOpts(c *C, tk *testkit.T } // nolint:unused -func (s *testSerialStatsSuite) checkForGlobalStatsWithOpts(c *C, tk *testkit.TestKit, t string, p string, topn, buckets int) { +func (s *testSerialStatsSuite) checkForGlobalStatsWithOpts(c *C, tk *testkit.TestKit, db, t, p string, topn, buckets int) { + tbl, err := s.do.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(t)) + c.Assert(err, IsNil) + + tblInfo := tbl.Meta() + physicalID := tblInfo.ID + if p != "global" { + for _, def := range tbl.Meta().GetPartitionInfo().Definitions { + if def.Name.L == p { + physicalID = def.ID + } + } + } + tblStats, err := s.do.StatsHandle().TableStatsFromStorage(tblInfo, physicalID, true, 0) + c.Assert(err, IsNil) + delta := buckets/2 + 10 - for _, isIdx := range []int{0, 1} { - c.Assert(len(tk.MustQuery(fmt.Sprintf("show stats_topn where table_name='%v' and partition_name='%v' and is_index=%v", t, p, isIdx)).Rows()), Equals, topn) - numBuckets := len(tk.MustQuery(fmt.Sprintf("show stats_buckets where table_name='%v' and partition_name='%v' and is_index=%v", t, p, isIdx)).Rows()) + for _, idxStats := range tblStats.Indices { + numTopN := idxStats.TopN.Num() + numBuckets := len(idxStats.Buckets) // since the hist-building algorithm doesn't stipulate the final bucket number to be equal to the expected number exactly, // we have to check the results by a range here. + c.Assert(numTopN, Equals, topn) + c.Assert(numBuckets, GreaterEqual, buckets-delta) + c.Assert(numBuckets, LessEqual, buckets+delta) + } + for _, colStats := range tblStats.Columns { + if len(colStats.Buckets) == 0 { + continue // it's not loaded + } + numTopN := colStats.TopN.Num() + numBuckets := len(colStats.Buckets) + c.Assert(numTopN, Equals, topn) c.Assert(numBuckets, GreaterEqual, buckets-delta) c.Assert(numBuckets, LessEqual, buckets+delta) } @@ -947,9 +973,9 @@ func (s *testSerialStatsSuite) TestAnalyzeGlobalStatsWithOpts(c *C) { sql := fmt.Sprintf("analyze table test_gstats_opt with %v topn, %v buckets", ca.topn, ca.buckets) if !ca.err { tk.MustExec(sql) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "global", ca.topn, ca.buckets) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "p0", ca.topn, ca.buckets) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "p1", ca.topn, ca.buckets) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "test_gstats_opt", "global", ca.topn, ca.buckets) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "test_gstats_opt", "p0", ca.topn, ca.buckets) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt", "test_gstats_opt", "p1", ca.topn, ca.buckets) } else { err := tk.ExecToErr(sql) c.Assert(err, NotNil) @@ -966,25 +992,25 @@ func (s *testSerialStatsSuite) TestAnalyzeGlobalStatsWithOpts2(c *C) { s.prepareForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2") tk.MustExec("analyze table test_gstats_opt2 with 20 topn, 50 buckets, 1000 samples") - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "global", 2, 50) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p0", 1, 50) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p1", 1, 50) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "global", 2, 50) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p0", 1, 50) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p1", 1, 50) // analyze a partition to let its options be different with others' tk.MustExec("analyze table test_gstats_opt2 partition p0 with 10 topn, 20 buckets") - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "global", 10, 20) // use new options - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p0", 10, 20) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p1", 1, 50) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "global", 10, 20) // use new options + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p0", 10, 20) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p1", 1, 50) tk.MustExec("analyze table test_gstats_opt2 partition p1 with 100 topn, 200 buckets") - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "global", 100, 200) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p0", 10, 20) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p1", 100, 200) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "global", 100, 200) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p0", 10, 20) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p1", 100, 200) tk.MustExec("analyze table test_gstats_opt2 partition p0 with 20 topn") // change back to 20 topn - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "global", 20, 256) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p0", 20, 256) - s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "p1", 100, 200) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "global", 20, 256) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p0", 20, 256) + s.checkForGlobalStatsWithOpts(c, tk, "test_gstats_opt2", "test_gstats_opt2", "p1", 100, 200) } func (s *testStatsSuite) TestGlobalStatsHealthy(c *C) {