Skip to content
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

planner: optimize performance of IndexUsage utilities #53195

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion pkg/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,14 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
sc.RuntimeStatsColl = execdetails.NewRuntimeStatsColl(reuseObj)

// also enable index usage collector
sc.IndexUsageCollector = ctx.NewStmtIndexUsageCollector()
if sc.IndexUsageCollector == nil {
sc.IndexUsageCollector = ctx.NewStmtIndexUsageCollector()
} else {
sc.IndexUsageCollector.Reset()
}
} else {
// turn off the index usage collector
sc.IndexUsageCollector = nil
}

sc.SetForcePlanCache(fixcontrol.GetBoolWithDefault(vars.OptimizerFixControl, fixcontrol.Fix49736, false))
Expand Down
11 changes: 10 additions & 1 deletion pkg/planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,16 @@ func loadTableStats(ctx sessionctx.Context, tblInfo *model.TableInfo, pid int64)

pctx := ctx.GetPlanCtx()
tableStats := getStatsTable(pctx, tblInfo, pid)
name, _ := getTblInfoForUsedStatsByPhysicalID(pctx, pid)

name := tblInfo.Name.O
partInfo := tblInfo.GetPartitionInfo()
if partInfo != nil {
for _, p := range partInfo.Definitions {
if p.ID == pid {
name += " " + p.Name.O
}
}
}
usedStats := &stmtctx.UsedStatsInfoForTable{
Name: name,
TblInfo: tblInfo,
Expand Down
26 changes: 22 additions & 4 deletions pkg/statistics/handle/usage/indexusage/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ func NewSample(queryTotal uint64, kvReqTotal uint64, rowAccess uint64, tableTota

type indexUsage map[GlobalIndexID]Sample

var indexUsagePool = sync.Pool{
New: func() any {
return make(indexUsage)
},
}

func (m indexUsage) updateByKey(id GlobalIndexID, sample Sample) {
item := m[id]
item.QueryTotal += sample.QueryTotal
Expand Down Expand Up @@ -127,7 +133,7 @@ type Collector struct {
// NewCollector create an index usage collector
func NewCollector() *Collector {
iuc := &Collector{
indexUsage: make(indexUsage),
indexUsage: indexUsagePool.Get().(indexUsage),
}
iuc.collector = collector.NewGlobalCollector[indexUsage](iuc.merge)

Expand All @@ -154,12 +160,16 @@ func (c *Collector) merge(delta indexUsage) {
defer c.Unlock()

c.indexUsage.merge(delta)

// return the `delta` to the pool
clear(delta)
indexUsagePool.Put(delta)
}

// SpawnSessionCollector creates a new session collector attached to this global collector
func (c *Collector) SpawnSessionCollector() *SessionIndexUsageCollector {
return &SessionIndexUsageCollector{
indexUsage: make(indexUsage),
indexUsage: indexUsagePool.Get().(indexUsage),
collector: c.collector.SpawnSession(),
}
}
Expand Down Expand Up @@ -219,7 +229,7 @@ func (s *SessionIndexUsageCollector) Report() {
return
}
if s.collector.SendDelta(s.indexUsage) {
s.indexUsage = make(indexUsage)
s.indexUsage = indexUsagePool.Get().(indexUsage)
}
}

Expand All @@ -230,7 +240,7 @@ func (s *SessionIndexUsageCollector) Flush() {
return
}
s.collector.SendDeltaSync(s.indexUsage)
s.indexUsage = make(indexUsage)
s.indexUsage = indexUsagePool.Get().(indexUsage)
}

// StmtIndexUsageCollector removes the duplicates index for recording `QueryTotal` in session collector
Expand Down Expand Up @@ -269,3 +279,11 @@ func (s *StmtIndexUsageCollector) Update(tableID int64, indexID int64, sample Sa

s.sessionCollector.Update(tableID, indexID, sample)
}

// Reset resets the recorded index in the collector to avoid re-allocating for each statement.
func (s *StmtIndexUsageCollector) Reset() {
s.Lock()
defer s.Unlock()

clear(s.recordedIndex)
}