planner: add more test cases for non-prep plan cache (#41608)

ref pingcap/tidb#36598
This commit is contained in:
Yuanjia Zhang
2023-02-20 22:09:13 +08:00
committed by GitHub
parent fca20d64da
commit bc52ce0739
2 changed files with 72 additions and 0 deletions

View File

@ -290,6 +290,71 @@ func TestNonPreparedPlanCacheFallback(t *testing.T) {
require.NotNil(t, err)
}
func TestNonPreparedPlanCacheFastPointGet(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`create table t (a int primary key, b int, unique key(b))`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`)
// fast plans have a higher priority than non-prep cache plan
tk.MustQuery(`explain format='brief' select a from t where a in (1, 2)`).Check(testkit.Rows(
`Batch_Point_Get 2.00 root table:t handle:[1 2], keep order:false, desc:false`))
tk.MustQuery(`select a from t where a in (1, 2)`).Check(testkit.Rows())
tk.MustQuery(`select a from t where a in (1, 2)`).Check(testkit.Rows())
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
tk.MustQuery(`explain format='brief' select b from t where b = 1`).Check(testkit.Rows(
`Point_Get 1.00 root table:t, index:b(b) `))
tk.MustQuery(`select b from t where b = 1`).Check(testkit.Rows())
tk.MustQuery(`select b from t where b = 1`).Check(testkit.Rows())
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
}
func TestNonPreparedPlanCacheSetOperations(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`create table t (a int)`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`)
// queries with set operations cannot hit the cache
for _, q := range []string{
`select * from t union select * from t`,
`select * from t union distinct select * from t`,
`select * from t union all select * from t`,
`select * from t except select * from t`,
`select * from t intersect select * from t`,
} {
tk.MustQuery(q).Check(testkit.Rows())
tk.MustQuery(q).Check(testkit.Rows())
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
}
}
func TestNonPreparedPlanCacheSpecialTables(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`create table t (a int)`)
tk.MustExec(`create definer='root'@'localhost' view t_v as select * from t`)
tk.MustExec(`create table t_p (a int) partition by hash(a) partitions 4`)
tk.MustExec(`create temporary table t_t (a int)`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`)
// queries that access partitioning tables, view, temporary tables or contain CTE cannot hit the cache.
for _, q := range []string{
`select * from t_v`,
`select * from t_p`,
`select * from t_t`,
`with t_cte as (select * from t) select * from t_cte`,
} {
tk.MustQuery(q).Check(testkit.Rows())
tk.MustQuery(q).Check(testkit.Rows())
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
}
}
func TestNonPreparedPlanCacheBasically(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

View File

@ -275,6 +275,9 @@ func (checker *nonPreparedPlanCacheableChecker) Enter(in ast.Node) (out ast.Node
if isTempTable(checker.schema, node) {
checker.cacheable = false
}
if isView(checker.schema, node) {
checker.cacheable = false
}
}
return in, !checker.cacheable
}
@ -301,6 +304,10 @@ func hasGeneratedCol(schema infoschema.InfoSchema, tn *ast.TableName) bool {
return false
}
func isView(schema infoschema.InfoSchema, tn *ast.TableName) bool {
return schema.TableIsView(tn.Schema, tn.Name)
}
func isTempTable(schema infoschema.InfoSchema, tn *ast.TableName) bool {
tb, err := schema.TableByName(tn.Schema, tn.Name)
if err != nil {