Skip to content

statistics: partition-level analyze options depend on tidb_partition_prune_mode #69952

Description

@mjonss

Enhancement

Partition-level analyze options behave differently depending on tidb_partition_prune_mode, even though that variable is settable per session and globally and is unrelated to the statement being run.

In genV2AnalyzeOptions (pkg/planner/core/planbuilder.go), a partition-targeted analyze in dynamic mode discards the statement's options and column choice entirely:

if !isAnalyzeTable && dynamicPrune && (len(astOpts) > 0 || astColChoice != ast.DefaultChoice) {
	astOpts = make(map[ast.AnalyzeOptionType]*uint64, 0)
	astColChoice = ast.DefaultChoice
	astColList = make([]*model.ColumnInfo, 0)
	b.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.NewNoStackError("Ignore columns and options when analyze partition in dynamic mode"))
}

In static mode the same statement is honoured and persisted per partition. saveAnalyzeOptions (pkg/executor/analyze.go) mirrors this by skipping partition rows in dynamic mode.

Two consequences:

  1. The same ANALYZE TABLE t PARTITION p0 WITH ... means two different things depending on a session variable, and options persisted in mysql.analyze_options under one mode are silently ignored under the other.
  2. ANALYZE TABLE t PARTITION p0 WITH DEFAULT <option> (added for statistics: support ANALYZE ... WITH DEFAULT <option> to reset persisted analyze options #69853) inherits the asymmetry. A reset targets persisted state rather than the current run, so arguably it should take effect regardless of the prune mode in force when it happens to be issued.

Proposal

Two directions, listed separately because they can be decided independently:

a) Make the DEFAULT reset mode-independent. Clearing a persisted partition option is a metadata operation on mysql.analyze_options. Ignoring it because of the current prune mode leaves the user unable to clear a value that a static-mode session persisted earlier.

b) Support per-partition options in dynamic mode generally. Dynamic mode still analyzes each partition and merges the results into global stats, so per-partition sampling is meaningful: a user who knows some partitions are more representative could sample those more heavily and the others less.

SAMPLES and SAMPLERATE are the coherent cases for (b). BUCKETS and TOPN are murkier, because the global merge re-buckets histograms and merges TopN across partitions, so uneven per-partition settings would give the merge uneven input. It may be right to allow the sampling options only.

Notes

Static prune mode is deprecated. If it is eventually removed, the entire partition-level analyze options feature disappears with it, since dynamic mode discards those options today. That is an additional argument for deciding (b) rather than letting the behavior lapse by attrition.

Found while reviewing the ANALYZE ... WITH DEFAULT implementation for #69853.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions