diff --git a/executor/seqtest/seq_executor_test.go b/executor/seqtest/seq_executor_test.go index 6c042340740e8..3e692a39a19df 100644 --- a/executor/seqtest/seq_executor_test.go +++ b/executor/seqtest/seq_executor_test.go @@ -624,7 +624,7 @@ func TestShowStatsHealthy(t *testing.T) { require.NoError(t, err) err = do.StatsHandle().Update(do.InfoSchema()) require.NoError(t, err) - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 19")) + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 0")) tk.MustExec("analyze table t") tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) tk.MustExec("delete from t") diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index 607c00931e493..ab701ce55bb3a 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -1096,7 +1096,7 @@ partition by range (a) ( require.NoError(t, dom.StatsHandle().DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, dom.StatsHandle().Update(dom.InfoSchema())) checkModifyAndCount(4, 10, 2, 4, 2, 6) - checkHealthy(60, 50, 66) + checkHealthy(33, 0, 50) } func TestGlobalStatsData(t *testing.T) { diff --git a/statistics/handle/update_test.go b/statistics/handle/update_test.go index ae2b65d88be30..e4aba902a8022 100644 --- a/statistics/handle/update_test.go +++ b/statistics/handle/update_test.go @@ -2212,19 +2212,30 @@ func TestAutoAnalyzeRatio(t *testing.T) { tk.MustExec("set global tidb_auto_analyze_start_time='00:00 +0000'") tk.MustExec("set global tidb_auto_analyze_end_time='23:59 +0000'") + getStatsHealthy := func() int { + rows := tk.MustQuery("show stats_healthy where db_name = 'test' and table_name = 't'").Rows() + require.Len(t, rows, 1) + healthy, err := strconv.Atoi(rows[0][3].(string)) + require.NoError(t, err) + return healthy + } + tk.MustExec("insert into t values (1)" + strings.Repeat(", (1)", 10)) require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 44) require.True(t, h.HandleAutoAnalyze(is)) tk.MustExec("delete from t limit 12") require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 61) require.False(t, h.HandleAutoAnalyze(is)) tk.MustExec("delete from t limit 4") require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 48) require.True(t, h.HandleAutoAnalyze(dom.InfoSchema())) } diff --git a/statistics/integration_test.go b/statistics/integration_test.go index a94a029f86381..179256d639677 100644 --- a/statistics/integration_test.go +++ b/statistics/integration_test.go @@ -520,14 +520,23 @@ func TestOutdatedStatsCheck(t *testing.T) { tk.MustExec("explain select * from t where a = 1") require.NoError(t, h.LoadNeededHistograms()) + getStatsHealthy := func() int { + rows := tk.MustQuery("show stats_healthy where db_name = 'test' and table_name = 't'").Rows() + require.Len(t, rows, 1) + healthy, err := strconv.Atoi(rows[0][3].(string)) + require.NoError(t, err) + return healthy + } + tk.MustExec("insert into t values (1)" + strings.Repeat(", (1)", 13)) // 34 rows require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 30) require.False(t, hasPseudoStats(tk.MustQuery("explain select * from t where a = 1").Rows())) - tk.MustExec("insert into t values (1)") // 35 rows require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 25) require.True(t, hasPseudoStats(tk.MustQuery("explain select * from t where a = 1").Rows())) tk.MustExec("analyze table t") @@ -535,11 +544,13 @@ func TestOutdatedStatsCheck(t *testing.T) { tk.MustExec("delete from t limit 24") // 11 rows require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 31) require.False(t, hasPseudoStats(tk.MustQuery("explain select * from t where a = 1").Rows())) tk.MustExec("delete from t limit 1") // 10 rows require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) + require.Equal(t, getStatsHealthy(), 28) require.True(t, hasPseudoStats(tk.MustQuery("explain select * from t where a = 1").Rows())) } diff --git a/statistics/table.go b/statistics/table.go index 6759020dec4f1..892e964011461 100644 --- a/statistics/table.go +++ b/statistics/table.go @@ -427,8 +427,12 @@ func (t *Table) GetStatsHealthy() (int64, bool) { return 0, false } var healthy int64 - if t.ModifyCount < t.Count { - healthy = int64((1.0 - float64(t.ModifyCount)/float64(t.Count)) * 100.0) + count := float64(t.Count) + if histCount := t.GetColRowCount(); histCount > 0 { + count = histCount + } + if float64(t.ModifyCount) < count { + healthy = int64((1.0 - float64(t.ModifyCount)/count) * 100.0) } else if t.ModifyCount == 0 { healthy = 100 }