diff --git a/statistics/handle/handle.go b/statistics/handle/handle.go index c028066a3cd02..d8613c4b4f0bd 100644 --- a/statistics/handle/handle.go +++ b/statistics/handle/handle.go @@ -1197,177 +1197,6 @@ func (h *Handle) FlushStats() { } } -func (h *Handle) indexStatsFromStorage(reader *statistics.StatsReader, row chunk.Row, table *statistics.Table, tableInfo *model.TableInfo) error { - histID := row.GetInt64(2) - distinct := row.GetInt64(3) - histVer := row.GetUint64(4) - nullCount := row.GetInt64(5) - statsVer := row.GetInt64(7) - idx := table.Indices[histID] - errorRate := statistics.ErrorRate{} - flag := row.GetInt64(8) - lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)) - if statistics.IsAnalyzed(flag) && !reader.IsHistory() { - h.mu.rateMap.clear(table.PhysicalID, histID, true) - } else if idx != nil { - errorRate = idx.ErrorRate - } - for _, idxInfo := range tableInfo.Indices { - if histID != idxInfo.ID { - continue - } - if idx == nil || idx.LastUpdateVersion < histVer { - hg, err := statistics.HistogramFromStorage(reader, table.PhysicalID, histID, types.NewFieldType(mysql.TypeBlob), distinct, 1, histVer, nullCount, 0, 0) - if err != nil { - return errors.Trace(err) - } - cms, topN, err := statistics.CMSketchAndTopNFromStorage(reader, table.PhysicalID, 1, idxInfo.ID) - if err != nil { - return errors.Trace(err) - } - fmSketch, err := statistics.FMSketchFromStorage(reader, table.PhysicalID, 1, histID) - if err != nil { - return errors.Trace(err) - } - idx = &statistics.Index{ - Histogram: *hg, - CMSketch: cms, - TopN: topN, - FMSketch: fmSketch, - Info: idxInfo, - ErrorRate: errorRate, - StatsVer: statsVer, - Flag: flag, - PhysicalID: table.PhysicalID, - } - if statsVer != statistics.Version0 { - idx.StatsLoadedStatus = statistics.NewStatsFullLoadStatus() - } - lastAnalyzePos.Copy(&idx.LastAnalyzePos) - } - break - } - if idx != nil { - table.Indices[histID] = idx - } else { - logutil.BgLogger().Debug("we cannot find index id in table info. It may be deleted.", zap.Int64("indexID", histID), zap.String("table", tableInfo.Name.O)) - } - return nil -} - -func (h *Handle) columnStatsFromStorage(reader *statistics.StatsReader, row chunk.Row, table *statistics.Table, tableInfo *model.TableInfo, loadAll bool) error { - histID := row.GetInt64(2) - distinct := row.GetInt64(3) - histVer := row.GetUint64(4) - nullCount := row.GetInt64(5) - totColSize := row.GetInt64(6) - statsVer := row.GetInt64(7) - correlation := row.GetFloat64(9) - lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)) - col := table.Columns[histID] - errorRate := statistics.ErrorRate{} - flag := row.GetInt64(8) - if statistics.IsAnalyzed(flag) && !reader.IsHistory() { - h.mu.rateMap.clear(table.PhysicalID, histID, false) - } else if col != nil { - errorRate = col.ErrorRate - } - for _, colInfo := range tableInfo.Columns { - if histID != colInfo.ID { - continue - } - isHandle := tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.GetFlag()) - // We will not load buckets if: - // 1. Lease > 0, and: - // 2. this column is not handle, and: - // 3. the column doesn't has any statistics before, and: - // 4. loadAll is false. - notNeedLoad := h.Lease() > 0 && - !isHandle && - (col == nil || !col.IsStatsInitialized() && col.LastUpdateVersion < histVer) && - !loadAll - if notNeedLoad { - count, err := statistics.ColumnCountFromStorage(reader, table.PhysicalID, histID, statsVer) - if err != nil { - return errors.Trace(err) - } - col = &statistics.Column{ - PhysicalID: table.PhysicalID, - Histogram: *statistics.NewHistogram(histID, distinct, nullCount, histVer, &colInfo.FieldType, 0, totColSize), - Info: colInfo, - Count: count + nullCount, - ErrorRate: errorRate, - IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.GetFlag()), - Flag: flag, - StatsVer: statsVer, - } - // When adding/modifying a column, we create its stats(all values are default values) without setting stats_ver. - // So we need add col.Count > 0 here. - if statsVer != statistics.Version0 || col.Count > 0 { - col.StatsLoadedStatus = statistics.NewStatsAllEvictedStatus() - } - lastAnalyzePos.Copy(&col.LastAnalyzePos) - col.Histogram.Correlation = correlation - break - } - if col == nil || col.LastUpdateVersion < histVer || loadAll { - hg, err := statistics.HistogramFromStorage(reader, table.PhysicalID, histID, &colInfo.FieldType, distinct, 0, histVer, nullCount, totColSize, correlation) - if err != nil { - return errors.Trace(err) - } - cms, topN, err := statistics.CMSketchAndTopNFromStorage(reader, table.PhysicalID, 0, colInfo.ID) - if err != nil { - return errors.Trace(err) - } - var fmSketch *statistics.FMSketch - if loadAll { - // FMSketch is only used when merging partition stats into global stats. When merging partition stats into global stats, - // we load all the statistics, i.e., loadAll is true. - fmSketch, err = statistics.FMSketchFromStorage(reader, table.PhysicalID, 0, histID) - if err != nil { - return errors.Trace(err) - } - } - col = &statistics.Column{ - PhysicalID: table.PhysicalID, - Histogram: *hg, - Info: colInfo, - CMSketch: cms, - TopN: topN, - FMSketch: fmSketch, - ErrorRate: errorRate, - IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.GetFlag()), - Flag: flag, - StatsVer: statsVer, - } - // Column.Count is calculated by Column.TotalRowCount(). Hence we don't set Column.Count when initializing col. - col.Count = int64(col.TotalRowCount()) - // When adding/modifying a column, we create its stats(all values are default values) without setting stats_ver. - // So we need add colHist.Count > 0 here. - if statsVer != statistics.Version0 || col.Count > 0 { - col.StatsLoadedStatus = statistics.NewStatsFullLoadStatus() - } - lastAnalyzePos.Copy(&col.LastAnalyzePos) - break - } - if col.TotColSize != totColSize { - newCol := *col - newCol.TotColSize = totColSize - col = &newCol - } - break - } - if col != nil { - table.Columns[col.ID] = col - } else { - // If we didn't find a Column or Index in tableInfo, we won't load the histogram for it. - // But don't worry, next lease the ddl will be updated, and we will load a same table for two times to - // avoid error. - logutil.BgLogger().Debug("we cannot find column in table info now. It may be deleted", zap.Int64("colID", histID), zap.String("table", tableInfo.Name.O)) - } - return nil -} - // TableStatsFromStorage loads table stats info from storage. func (h *Handle) TableStatsFromStorage(tableInfo *model.TableInfo, physicalID int64, loadAll bool, snapshot uint64) (_ *statistics.Table, err error) { reader, err := h.getGlobalStatsReader(snapshot) diff --git a/statistics/interact_with_storage.go b/statistics/interact_with_storage.go index 8231b90dec5d2..fdf27d601448d 100644 --- a/statistics/interact_with_storage.go +++ b/statistics/interact_with_storage.go @@ -169,8 +169,8 @@ func FMSketchFromStorage(reader *StatsReader, tblID int64, isIndex, histID int64 return DecodeFMSketch(rows[0].GetBytes(0)) } -// ColumnCountFromStorage reads column count from storage -func ColumnCountFromStorage(reader *StatsReader, tableID, colID, statsVer int64) (int64, error) { +// columnCountFromStorage reads column count from storage +func columnCountFromStorage(reader *StatsReader, tableID, colID, statsVer int64) (int64, error) { count := int64(0) rows, _, err := reader.Read("select sum(count) from mysql.stats_buckets where table_id = %? and is_index = 0 and hist_id = %?", tableID, colID) if err != nil { @@ -357,7 +357,7 @@ func columnStatsFromStorage(reader *StatsReader, row chunk.Row, table *Table, ta // Here is //For one column, if there is no stats for it in the storage(analyze is never) if notNeedLoad { - count, err := ColumnCountFromStorage(reader, table.PhysicalID, histID, statsVer) + count, err := columnCountFromStorage(reader, table.PhysicalID, histID, statsVer) if err != nil { return errors.Trace(err) }