Skip to content

Commit

Permalink
planner: bypass plan cache for cached PointGet plan (#53686)
Browse files Browse the repository at this point in the history
close #53687
  • Loading branch information
qw4990 authored May 30, 2024
1 parent 9745a16 commit 2038b1f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
18 changes: 15 additions & 3 deletions pkg/planner/core/plan_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ func planCachePreprocess(ctx context.Context, sctx sessionctx.Context, isNonPrep
// cached plan once the schema version is changed.
// Cached plan in prepared struct does NOT have a "cache key" with
// schema version like prepared plan cache key
stmt.PointGet.pointPlan = nil
stmt.PointGet.columnNames = nil
stmt.PointGet.pointPlanHints = nil
stmt.PointGet.Executor = nil
stmt.PointGet.ColumnInfos = nil
// If the schema version has changed we need to preprocess it again,
Expand Down Expand Up @@ -219,9 +222,13 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context,
if stmtCtx.UseCache() {
var cacheVal kvcache.Value
var hit, isPointPlan bool
if stmt.PointGet.Executor != nil { // if it's PointGet Plan, no need to use MatchOpts
cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, nil)
isPointPlan = true
if stmt.PointGet.pointPlan != nil { // if it's PointGet Plan, no need to use MatchOpts
cacheVal = &PlanCacheValue{
Plan: stmt.PointGet.pointPlan,
OutputColumns: stmt.PointGet.columnNames,
stmtHints: stmt.PointGet.pointPlanHints,
}
isPointPlan, hit = true, true
} else {
matchOpts = GetMatchOpts(sctx, is, stmt, params)
cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, matchOpts)
Expand Down Expand Up @@ -316,6 +323,11 @@ func generateNewPlan(ctx context.Context, sctx sessionctx.Context, isNonPrepared
stmtCtx.SetPlan(p)
stmtCtx.SetPlanDigest(stmt.NormalizedPlan, stmt.PlanDigest)
sctx.GetSessionPlanCache().Put(cacheKey, cached, matchOpts)
if _, ok := p.(*PointGetPlan); ok {
stmt.PointGet.pointPlan = p
stmt.PointGet.columnNames = names
stmt.PointGet.pointPlanHints = stmtCtx.StmtHints.Clone()
}
}
sessVars.FoundInPlanCache = false
return p, names, err
Expand Down
7 changes: 7 additions & 0 deletions pkg/planner/core/plan_cache_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,13 @@ func (*PlanCacheQueryFeatures) Leave(in ast.Node) (out ast.Node, ok bool) {
// PointGetExecutorCache caches the PointGetExecutor to further improve its performance.
// Don't forget to reset this executor when the prior plan is invalid.
type PointGetExecutorCache struct {
// Special (or tricky) optimization for PointGet Plan.
// Store the PointGet Plan in PlanCacheStmt directly to bypass the LRU Cache to gain some performance improvement.
// There is around 3% improvement, BenchmarkPreparedPointGet: 6450 ns/op --> 6250 ns/op.
pointPlan base.Plan
pointPlanHints *hint.StmtHints
columnNames types.NameSlice

ColumnInfos any
// Executor is only used for point get scene.
// Notice that we should only cache the PointGetExecutor that have a snapshot with MaxTS in it.
Expand Down

0 comments on commit 2038b1f

Please sign in to comment.