planner: add binding info for explain stmt (#26403)

This commit is contained in:
Chengpeng Yan
2021-08-02 16:57:06 +08:00
committed by GitHub
parent e199323f5c
commit df908bf31f
2 changed files with 29 additions and 1 deletions

View File

@ -1891,6 +1891,24 @@ func (s *testSuite) TestReCreateBind(c *C) {
c.Assert(rows[0][3], Equals, "using")
}
func (s *testSuite) TestExplainShowBindSQL(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.cleanBindingEnv(tk)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, key(a))")
tk.MustExec("create global binding for select * from t using select * from t use index(a)")
tk.MustQuery("select original_sql, bind_sql from mysql.bind_info where default_db != 'mysql'").Check(testkit.Rows(
"select * from `test` . `t` SELECT * FROM `test`.`t` USE INDEX (`a`)",
))
tk.MustExec("explain select * from t")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Using the bindSQL: SELECT * FROM `test`.`t` USE INDEX (`a`)"))
tk.MustExec("explain analyze select * from t")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Using the bindSQL: SELECT * FROM `test`.`t` USE INDEX (`a`)"))
}
func (s *testSuite) TestDMLIndexHintBind(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.cleanBindingEnv(tk)

View File

@ -170,11 +170,17 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
if binding != nil && binding.Status == bindinfo.Using {
if sctx.GetSessionVars().UsePlanBaselines {
stmtHints, warns = handleStmtHints(binding.Hint.GetFirstTableHints())
if _, ok := stmtNode.(*ast.ExplainStmt); ok {
sctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("Using the bindSQL: %v", binding.BindSQL))
}
}
return bestPlan, names, nil
}
bestCostAmongHints := math.MaxFloat64
var bestPlanAmongHints plannercore.Plan
var (
bestPlanAmongHints plannercore.Plan
bestPlanBindSQL string
)
originHints := hint.CollectHint(stmtNode)
// Try to find the best binding.
for _, binding := range bindRecord.Bindings {
@ -201,8 +207,12 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
}
bestCostAmongHints = cost
bestPlanAmongHints = plan
bestPlanBindSQL = binding.BindSQL
}
}
if _, ok := stmtNode.(*ast.ExplainStmt); ok && bestPlanBindSQL != "" {
sctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("Using the bindSQL: %v", bestPlanBindSQL))
}
// 1. If it is a select query.
// 2. If there is already a evolution task, we do not need to handle it again.
// 3. If the origin binding contain `read_from_storage` hint, we should ignore the evolve task.