diff --git a/cmd/go-tpc/tpch.go b/cmd/go-tpc/tpch.go index 8fb51b1..aa6c738 100644 --- a/cmd/go-tpc/tpch.go +++ b/cmd/go-tpc/tpch.go @@ -34,6 +34,7 @@ func executeTpch(action string) { tpchConfig.DBName = dbName tpchConfig.PrepareThreads = threads tpchConfig.QueryNames = strings.Split(tpchConfig.RawQueries, ",") + tpchConfig.QueryTuningConfig.Vars = strings.Split(tpchConfig.QueryTuningConfig.VarsRaw, ";") w := tpch.NewWorkloader(globalDB, &tpchConfig) timeoutCtx, cancel := context.WithTimeout(globalCtx, totalTime) defer cancel() @@ -130,6 +131,15 @@ func registerTpch(root *cobra.Command) { "", "Name of plan Replayer file dumps") + cmdPrepare.PersistentFlags().BoolVar(&tpchConfig.QueryTuningConfig.Enable, + "enable-query-tuning", + true, + "Enable query tuning by setting specified session variables") + cmdPrepare.PersistentFlags().StringVar(&tpchConfig.QueryTuningConfig.VarsRaw, + "query-tuning-vars", + "tidb_default_string_match_selectivity=0.1;tidb_opt_join_reorder_threshold=60;tidb_prefer_broadcast_join_by_exchange_data_size=ON", + "Specify a sequence of session variables to set before executing each query, in the form of 'name=value', separated by semicolon. Defaulted to some variables known effective for tpch queries.") + var cmdCleanup = &cobra.Command{ Use: "cleanup", Short: "Cleanup data for the workload", diff --git a/tpch/workload.go b/tpch/workload.go index 904ef57..36eecb3 100644 --- a/tpch/workload.go +++ b/tpch/workload.go @@ -29,6 +29,12 @@ type analyzeConfig struct { IndexSerialScanConcurrency int } +type queryTuningConfig struct { + Enable bool + VarsRaw string + Vars []string +} + // Config is the configuration for tpch workload type Config struct { Driver string @@ -45,6 +51,8 @@ type Config struct { PlanReplayerConfig replayer.PlanReplayerConfig EnablePlanReplayer bool + QueryTuningConfig queryTuningConfig + // for prepare command only OutputType string OutputDir string @@ -197,6 +205,18 @@ func (w *Workloader) CheckPrepare(ctx context.Context, threadID int) error { return nil } +func (w *Workloader) setQueryTuningVars(ctx context.Context) error { + if w.cfg.QueryTuningConfig.Enable && w.cfg.Driver != "mysql" { + conn := w.getState(ctx).Conn + for _, v := range w.cfg.QueryTuningConfig.Vars { + if _, err := conn.ExecContext(ctx, fmt.Sprintf("SET @@session.%s", v)); err != nil { + return err + } + } + } + return nil +} + // Run runs workload func (w *Workloader) Run(ctx context.Context, threadID int) error { s := w.getState(ctx) @@ -207,6 +227,10 @@ func (w *Workloader) Run(ctx context.Context, threadID int) error { } } + if err := w.setQueryTuningVars(ctx); err != nil { + return fmt.Errorf("set query tuning variables failed %v", err) + } + queryName := w.cfg.QueryNames[s.queryIdx%len(w.cfg.QueryNames)] query := query(w.cfg.Driver, queryName) // only for driver == mysql and EnablePlanReplayer == true