Skip to content

Commit

Permalink
fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
qw4990 committed Apr 12, 2023
1 parent 082e6d6 commit 9ac8281
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 4 deletions.
58 changes: 58 additions & 0 deletions planner/core/plan_cache_test.go
Expand Up @@ -388,6 +388,64 @@ func TestNonPreparedPlanCacheSQLMode(t *testing.T) {
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
}

func TestPreparedPlanCacheLargePlan(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec("create table t(a int, b int, c varchar(2048))")

baseSQL := "select * from t, t t1 where t1.c=space(2048) and t.c=space(2048) and t.a=t1.b"
var baseSQLs []string
for i := 0; i < 30; i++ {
baseSQLs = append(baseSQLs, baseSQL)
}

tk.MustExec("prepare st from '" + strings.Join(baseSQLs[:15], " union all ") + "'")
tk.MustExec("execute st")
tk.MustExec("execute st")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // less than 2MB threshold

tk.MustExec("prepare st from '" + strings.Join(baseSQLs[:30], " union all ") + "'")
tk.MustExec("execute st")
tk.MustExec("execute st")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // large than 2MB threshold
}

func TestPreparedPlanCacheLongInList(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec("create table t(a int, b int)")

genInList := func(l int) string {
var elements []string
for i := 0; i < l; i++ {
elements = append(elements, fmt.Sprintf("%v", i))
}
return "(" + strings.Join(elements, ",") + ")"
}

tk.MustExec(fmt.Sprintf(`prepare st_99 from 'select * from t where a in %v'`, genInList(99)))
tk.MustExec(`execute st_99`)
tk.MustExec(`execute st_99`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))

tk.MustExec(fmt.Sprintf(`prepare st_101 from 'select * from t where a in %v'`, genInList(101)))
tk.MustExec(`execute st_101`)
tk.MustExec(`execute st_101`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))

tk.MustExec(fmt.Sprintf(`prepare st_49_50 from 'select * from t where a in %v and b in %v'`, genInList(49), genInList(50)))
tk.MustExec(`execute st_49_50`)
tk.MustExec(`execute st_49_50`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))

tk.MustExec(fmt.Sprintf(`prepare st_49_52 from 'select * from t where a in %v and b in %v'`, genInList(49), genInList(52)))
tk.MustExec(`execute st_49_52`)
tk.MustExec(`execute st_49_52`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
}

func TestPreparedPlanCacheStats(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down
21 changes: 17 additions & 4 deletions planner/core/plan_cacheable_checker.go
Expand Up @@ -29,6 +29,7 @@ import (
driver "github.com/pingcap/tidb/types/parser_driver"
"github.com/pingcap/tidb/util/filter"
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/size"
"go.uber.org/zap"
)

Expand All @@ -51,9 +52,10 @@ func CacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.Info
return false, "not a SELECT/UPDATE/INSERT/DELETE/SET statement"
}
checker := cacheableChecker{
sctx: sctx,
cacheable: true,
schema: is,
sctx: sctx,
cacheable: true,
schema: is,
sumInListLen: 0,
}
node.Accept(&checker)
return checker.cacheable, checker.reason
Expand All @@ -65,6 +67,8 @@ type cacheableChecker struct {
cacheable bool
schema infoschema.InfoSchema
reason string // reason why cannot use plan-cache

sumInListLen int // the accumulated number of elements in all in-lists
}

// Enter implements Visitor interface.
Expand Down Expand Up @@ -114,7 +118,13 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren
return in, true
}
}

case *ast.PatternInExpr:
checker.sumInListLen += len(node.List)
if checker.sumInListLen > 100 { // to save memory
checker.cacheable = false
checker.reason = "too many values in in-list (more than 100)"
return in, true
}
case *ast.VariableExpr:
checker.cacheable = false
checker.reason = "query has user-defined variables is un-cacheable"
Expand Down Expand Up @@ -594,6 +604,9 @@ func isPlanCacheable(sctx sessionctx.Context, p Plan, paramNum, limitParamNum in
if hasSubQuery && !sctx.GetSessionVars().EnablePlanCacheForSubquery {
return false, "the switch 'tidb_enable_plan_cache_for_subquery' is off"
}
if uint64(pp.MemoryUsage()) > 2*size.MB { // to save memory
return false, "plan is too large(>2MB)"
}
return isPhysicalPlanCacheable(sctx, pp, paramNum, limitParamNum, false)
}

Expand Down

0 comments on commit 9ac8281

Please sign in to comment.