Skip to content

Commit

Permalink
executor: fix fast analyze on single index (pingcap#19662)
Browse files Browse the repository at this point in the history
* executor: fix fast analyze single index

* use idxCol.offset instead of compare column name

Co-authored-by: ti-srebot <[email protected]>
  • Loading branch information
lysu and ti-srebot authored Sep 3, 2020
1 parent d8b3d32 commit 66de018
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 20 deletions.
49 changes: 29 additions & 20 deletions executor/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,24 +771,20 @@ func (e *AnalyzeFastExec) buildSampTask() (err error) {
return nil
}

func (e *AnalyzeFastExec) decodeValues(handle kv.Handle, sValue []byte) (values map[int64]types.Datum, err error) {
func (e *AnalyzeFastExec) decodeValues(handle kv.Handle, sValue []byte, wantCols map[int64]*types.FieldType) (values map[int64]types.Datum, err error) {
loc := e.ctx.GetSessionVars().Location()
colID2FieldTypes := make(map[int64]*types.FieldType, len(e.colsInfo))
for _, col := range e.colsInfo {
colID2FieldTypes[col.ID] = &col.FieldType
}
values, err = tablecodec.DecodeRowToDatumMap(sValue, colID2FieldTypes, loc)
values, err = tablecodec.DecodeRowToDatumMap(sValue, wantCols, loc)
if err != nil || e.handleCols == nil {
return values, err
}
colID2FieldTypes = make(map[int64]*types.FieldType, len(e.colsInfo))
wantCols = make(map[int64]*types.FieldType, e.handleCols.NumCols())
handleColIDs := make([]int64, e.handleCols.NumCols())
for i := 0; i < e.handleCols.NumCols(); i++ {
c := e.handleCols.GetCol(i)
handleColIDs[i] = c.ID
colID2FieldTypes[c.ID] = c.RetType
wantCols[c.ID] = c.RetType
}
return tablecodec.DecodeHandleToDatumMap(handle, handleColIDs, colID2FieldTypes, loc, values)
return tablecodec.DecodeHandleToDatumMap(handle, handleColIDs, wantCols, loc, values)
}

func (e *AnalyzeFastExec) getValueByInfo(colInfo *model.ColumnInfo, values map[int64]types.Datum) (types.Datum, error) {
Expand All @@ -805,9 +801,26 @@ func (e *AnalyzeFastExec) updateCollectorSamples(sValue []byte, sKey kv.Key, sam
if err != nil {
return err
}

// Decode cols for analyze table
wantCols := make(map[int64]*types.FieldType, len(e.colsInfo))
for _, col := range e.colsInfo {
wantCols[col.ID] = &col.FieldType
}

// Pre-build index->cols relationship and refill wantCols if not exists(analyze index)
index2Cols := make([][]*model.ColumnInfo, len(e.idxsInfo))
for i, idxInfo := range e.idxsInfo {
for _, idxCol := range idxInfo.Columns {
colInfo := e.tblInfo.Columns[idxCol.Offset]
index2Cols[i] = append(index2Cols[i], colInfo)
wantCols[colInfo.ID] = &colInfo.FieldType
}
}

// Decode the cols value in order.
var values map[int64]types.Datum
values, err = e.decodeValues(handle, sValue)
values, err = e.decodeValues(handle, sValue, wantCols)
if err != nil {
return err
}
Expand Down Expand Up @@ -841,17 +854,13 @@ func (e *AnalyzeFastExec) updateCollectorSamples(sValue []byte, sKey kv.Key, sam
// Update the indexes' collectors.
for j, idxInfo := range e.idxsInfo {
idxVals := make([]types.Datum, 0, len(idxInfo.Columns))
for _, idxCol := range idxInfo.Columns {
for _, colInfo := range e.tblInfo.Columns {
if colInfo.Name == idxCol.Name {
v, err := e.getValueByInfo(colInfo, values)
if err != nil {
return err
}
idxVals = append(idxVals, v)
break
}
cols := index2Cols[j]
for _, colInfo := range cols {
v, err := e.getValueByInfo(colInfo, values)
if err != nil {
return err
}
idxVals = append(idxVals, v)
}
var bytes []byte
bytes, err = codec.EncodeKey(e.ctx.GetSessionVars().StmtCtx, bytes, idxVals...)
Expand Down
8 changes: 8 additions & 0 deletions executor/analyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,14 @@ func (s *testSuite1) TestAnalyzeIndex(c *C) {
tk.MustExec("insert into t1(id, v) values(1, 2), (2, 2), (3, 2), (4, 2), (5, 1), (6, 3), (7, 4)")
tk.MustExec("analyze table t1 index k")
c.Assert(len(tk.MustQuery("show stats_buckets where table_name = 't1' and column_name = 'k' and is_index = 1").Rows()), Greater, 0)

func() {
defer tk.MustExec("set @@session.tidb_enable_fast_analyze=0")
tk.MustExec("drop stats t1")
tk.MustExec("set @@session.tidb_enable_fast_analyze=1")
tk.MustExec("analyze table t1 index k")
c.Assert(len(tk.MustQuery("show stats_buckets where table_name = 't1' and column_name = 'k' and is_index = 1").Rows()), Greater, 1)
}()
}

func (s *testSuite1) TestAnalyzeIncremental(c *C) {
Expand Down

0 comments on commit 66de018

Please sign in to comment.