planner: optimize the parameterization(parser.Restore) performance for non-prep plan cache (#43018)

ref pingcap/tidb#36598
This commit is contained in:
Yuanjia Zhang
2023-04-13 15:41:02 +08:00
committed by GitHub
parent 2002ca106e
commit 8a1e0c422e
2 changed files with 18 additions and 9 deletions

View File

@ -349,16 +349,22 @@ func (rf RestoreFlags) HasRestoreForNonPrepPlanCache() bool {
return rf.has(RestoreForNonPrepPlanCache)
}
// RestoreWriter is the interface for `Restore` to write.
type RestoreWriter interface {
io.Writer
io.StringWriter
}
// RestoreCtx is `Restore` context to hold flags and writer.
type RestoreCtx struct {
Flags RestoreFlags
In io.Writer
In RestoreWriter
DefaultDB string
CTERestorer
}
// NewRestoreCtx returns a new `RestoreCtx`.
func NewRestoreCtx(flags RestoreFlags, in io.Writer) *RestoreCtx {
func NewRestoreCtx(flags RestoreFlags, in RestoreWriter) *RestoreCtx {
return &RestoreCtx{Flags: flags, In: in, DefaultDB: ""}
}
@ -427,12 +433,16 @@ func (ctx *RestoreCtx) WriteName(name string) {
name = strings.Replace(name, "`", "``", -1)
quotes = "`"
}
fmt.Fprint(ctx.In, quotes, name, quotes)
// use `WriteString` directly instead of `fmt.Fprint` to get a better performance.
ctx.In.WriteString(quotes)
ctx.In.WriteString(name)
ctx.In.WriteString(quotes)
}
// WritePlain writes the plain text into writer without any handling.
func (ctx *RestoreCtx) WritePlain(plainText string) {
fmt.Fprint(ctx.In, plainText)
ctx.In.WriteString(plainText)
}
// WritePlainf write the plain text into writer without any handling.

View File

@ -15,9 +15,9 @@
package core
import (
"bytes"
"context"
"errors"
"strings"
"sync"
"github.com/pingcap/tidb/expression"
@ -41,8 +41,7 @@ var (
return pr
}}
paramCtxPool = sync.Pool{New: func() interface{} {
buf := new(strings.Builder)
buf.Reset()
buf := new(bytes.Buffer)
restoreCtx := format.NewRestoreCtx(format.RestoreForNonPrepPlanCache|format.RestoreStringWithoutCharset|format.RestoreStringSingleQuotes|format.RestoreNameBackQuotes, buf)
return restoreCtx
}}
@ -106,14 +105,14 @@ func ParameterizeAST(ctx context.Context, sctx sessionctx.Context, stmt ast.Stmt
defer func() {
pr.Reset()
paramReplacerPool.Put(pr)
pCtx.In.(*strings.Builder).Reset()
pCtx.In.(*bytes.Buffer).Reset()
paramCtxPool.Put(pCtx)
}()
stmt.Accept(pr)
if err := stmt.Restore(pCtx); err != nil {
return "", nil, err
}
paramSQL, params = pCtx.In.(*strings.Builder).String(), pr.params
paramSQL, params = pCtx.In.(*bytes.Buffer).String(), pr.params
return
}