planner: refactor a few code of plan cache (#54058)
ref pingcap/tidb#54057
This commit is contained in:
@ -253,61 +253,13 @@ func (l *LRUPlanCache) memoryControl() {
|
||||
// PickPlanFromBucket pick one plan from bucket
|
||||
func (l *LRUPlanCache) pickFromBucket(bucket map[*list.Element]struct{}, matchOpts *utilpc.PlanCacheMatchOpts) (*list.Element, bool) {
|
||||
for k := range bucket {
|
||||
if matchOpts == nil { // for PointGet Plan
|
||||
if matchCachedPlan(l.sctx, k.Value.(*planCacheEntry).PlanValue.(*PlanCacheValue), matchOpts) {
|
||||
return k, true
|
||||
}
|
||||
|
||||
plan := k.Value.(*planCacheEntry).PlanValue.(*PlanCacheValue)
|
||||
// check param types' compatibility
|
||||
ok1 := checkTypesCompatibility4PC(plan.matchOpts.ParamTypes, matchOpts.ParamTypes)
|
||||
if !ok1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// check limit offset and key if equal and check switch if enabled
|
||||
ok2 := checkUint64SliceIfEqual(plan.matchOpts.LimitOffsetAndCount, matchOpts.LimitOffsetAndCount)
|
||||
if !ok2 {
|
||||
continue
|
||||
}
|
||||
if len(plan.matchOpts.LimitOffsetAndCount) > 0 && !l.sctx.GetSessionVars().EnablePlanCacheForParamLimit {
|
||||
// offset and key slice matched, but it is a plan with param limit and the switch is disabled
|
||||
continue
|
||||
}
|
||||
// check subquery switch state
|
||||
if plan.matchOpts.HasSubQuery && !l.sctx.GetSessionVars().EnablePlanCacheForSubquery {
|
||||
continue
|
||||
}
|
||||
// table stats has changed
|
||||
// this check can be disabled by turning off system variable tidb_plan_cache_invalidation_on_fresh_stats
|
||||
if l.sctx.GetSessionVars().PlanCacheInvalidationOnFreshStats &&
|
||||
plan.matchOpts.StatsVersionHash != matchOpts.StatsVersionHash {
|
||||
continue
|
||||
}
|
||||
|
||||
// below are some SQL variables that can affect the plan
|
||||
if plan.matchOpts.ForeignKeyChecks != matchOpts.ForeignKeyChecks {
|
||||
continue
|
||||
}
|
||||
return k, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func checkUint64SliceIfEqual(a, b []uint64) bool {
|
||||
if (a == nil && b != nil) || (a != nil && b == nil) {
|
||||
return false
|
||||
}
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// updateInstanceMetric update the memory usage and plan num for show in grafana
|
||||
func (l *LRUPlanCache) updateInstanceMetric(in, out *planCacheEntry) {
|
||||
updateInstancePlanNum(in, out)
|
||||
|
||||
@ -750,3 +750,37 @@ func parseParamTypes(sctx sessionctx.Context, params []expression.Expression) (p
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// matchCachedPlan checks whether this plan is matched with these match-options.
|
||||
func matchCachedPlan(sctx sessionctx.Context, value *PlanCacheValue, matchOpts *utilpc.PlanCacheMatchOpts) bool {
|
||||
if matchOpts == nil { // if PointGet, the matchOpts is nil
|
||||
return true
|
||||
}
|
||||
if !checkTypesCompatibility4PC(value.matchOpts.ParamTypes, matchOpts.ParamTypes) {
|
||||
return false
|
||||
}
|
||||
// check limit offset and key if equal and check switch if enabled
|
||||
if !slices.Equal(value.matchOpts.LimitOffsetAndCount, matchOpts.LimitOffsetAndCount) {
|
||||
return false
|
||||
}
|
||||
if len(value.matchOpts.LimitOffsetAndCount) > 0 && !sctx.GetSessionVars().EnablePlanCacheForParamLimit {
|
||||
// offset and key slice matched, but it is a plan with param limit and the switch is disabled
|
||||
return false
|
||||
}
|
||||
// check subquery switch state
|
||||
if value.matchOpts.HasSubQuery && !sctx.GetSessionVars().EnablePlanCacheForSubquery {
|
||||
return false
|
||||
}
|
||||
|
||||
// table stats has changed
|
||||
// this check can be disabled by turning off system variable tidb_plan_cache_invalidation_on_fresh_stats
|
||||
if sctx.GetSessionVars().PlanCacheInvalidationOnFreshStats &&
|
||||
value.matchOpts.StatsVersionHash != matchOpts.StatsVersionHash {
|
||||
return false
|
||||
}
|
||||
// below are some SQL variables that can affect the plan
|
||||
if value.matchOpts.ForeignKeyChecks != matchOpts.ForeignKeyChecks {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user