-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: support auto analyze partition table #7789
Changes from all commits
4f175f9
d93f8b9
788c803
049d51e
5e12bad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -707,31 +707,52 @@ func (h *Handle) HandleAutoAnalyze(is infoschema.InfoSchema) error { | |
tbls := is.SchemaTables(model.NewCIStr(db)) | ||
for _, tbl := range tbls { | ||
tblInfo := tbl.Meta() | ||
statsTbl := h.GetTableStats(tblInfo) | ||
if statsTbl.Pseudo || statsTbl.Count < AutoAnalyzeMinCnt { | ||
continue | ||
} | ||
pi := tblInfo.GetPartitionInfo() | ||
tblName := "`" + db + "`.`" + tblInfo.Name.O + "`" | ||
if NeedAnalyzeTable(statsTbl, 20*h.Lease, autoAnalyzeRatio, start, end, time.Now()) { | ||
if pi == nil { | ||
statsTbl := h.GetTableStats(tblInfo) | ||
sql := fmt.Sprintf("analyze table %s", tblName) | ||
log.Infof("[stats] auto analyze table %s now", tblName) | ||
return errors.Trace(h.execAutoAnalyze(sql)) | ||
} | ||
for _, idx := range tblInfo.Indices { | ||
if idx.State != model.StatePublic { | ||
continue | ||
analyzed, err := h.autoAnalyzeTable(tblInfo, statsTbl, start, end, autoAnalyzeRatio, sql) | ||
if analyzed { | ||
return err | ||
} | ||
if _, ok := statsTbl.Indices[idx.ID]; !ok { | ||
sql := fmt.Sprintf("analyze table %s index `%s`", tblName, idx.Name.O) | ||
log.Infof("[stats] auto analyze index `%s` for table %s now", idx.Name.O, tblName) | ||
return errors.Trace(h.execAutoAnalyze(sql)) | ||
continue | ||
} | ||
for _, def := range pi.Definitions { | ||
sql := fmt.Sprintf("analyze table %s partition `%s`", tblName, def.Name.O) | ||
statsTbl := h.GetPartitionStats(tblInfo, def.ID) | ||
analyzed, err := h.autoAnalyzeTable(tblInfo, statsTbl, start, end, autoAnalyzeRatio, sql) | ||
if analyzed { | ||
return err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if one of the partition is analyzed, the rest of the partitions can never get a change to be analyzed, I think we should continue to analyze other partitions instead just return and terminate the analyze command. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason that we only trigger one analyze once a time is that we can get the most updated auto analyze parameters. The rest of the partition can wait for the next round which is just 3s after. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What does this mean? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In https://github.com/pingcap/tidb/blob/master/statistics/update.go#L654, we get the parameters like analyze time period, so if we continue analyze other tables, we may not use the latest parameters. |
||
} | ||
continue | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (h *Handle) autoAnalyzeTable(tblInfo *model.TableInfo, statsTbl *Table, start, end time.Time, ratio float64, sql string) (bool, error) { | ||
if statsTbl.Pseudo || statsTbl.Count < AutoAnalyzeMinCnt { | ||
return false, nil | ||
} | ||
if NeedAnalyzeTable(statsTbl, 20*h.Lease, ratio, start, end, time.Now()) { | ||
log.Infof("[stats] auto %s now", sql) | ||
return true, h.execAutoAnalyze(sql) | ||
} | ||
for _, idx := range tblInfo.Indices { | ||
if idx.State != model.StatePublic { | ||
continue | ||
} | ||
if _, ok := statsTbl.Indices[idx.ID]; !ok { | ||
sql = fmt.Sprintf("%s index `%s`", sql, idx.Name.O) | ||
log.Infof("[stats] auto %s now", sql) | ||
return true, h.execAutoAnalyze(sql) | ||
} | ||
} | ||
return false, nil | ||
} | ||
|
||
func (h *Handle) execAutoAnalyze(sql string) error { | ||
startTime := time.Now() | ||
_, _, err := h.restrictedExec.ExecRestrictedSQL(nil, sql) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we analyze all partitions at once instead of only one partition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think only one partition is better because the partition stats is independent.