code: func NeedAnalyzeTable(tbl *statistics.Table, limit time.Duration, autoAnalyzeRatio float64, start, end, now time.Time) (bool, string) {
  	analyzed := TableAnalyzed(tbl)
  	if !analyzed {
  		t := time.Unix(0, oracle.ExtractPhysical(tbl.Version)*int64(time.Millisecond))
  		dur := time.Since(t)
  		return dur >= limit, fmt.Sprintf("table unanalyzed, time since last updated %vs", dur)
  	}
  	// Auto analyze is disabled.
  	if autoAnalyzeRatio == 0 {
  		return false, ""
  	}
  	// No need to analyze it.
  	if float64(tbl.ModifyCount)/float64(tbl.Count) <= autoAnalyzeRatio {
  		return false, ""
  	}
  	// Tests if current time is within the time period.
  	return withinTimePeriod(start, end, now), fmt.Sprintf("too many modifications(%v/%v)", tbl.ModifyCount, tbl.Count)
  }
docs: // NeedAnalyzeTable checks if we need to analyze the table:
  // 1. If the table has never been analyzed, we need to analyze it when it has
  //    not been modified for a while.
  // 2. If the table had been analyzed before, we need to analyze it when
  //    "tbl.ModifyCount/tbl.Count > autoAnalyzeRatio" and the current time is
  //    between `start` and `end`.