Skip to content

Commit

Permalink
planner: allow to use dynamic mode to access partitioning tables with…
Browse files Browse the repository at this point in the history
…out global-stats (#44264) (#44345)

close #44262
  • Loading branch information
qw4990 committed Jun 2, 2023
1 parent bb2e845 commit ede0681
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
29 changes: 29 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8022,6 +8022,35 @@ func TestExplainAnalyzeDMLCommit(t *testing.T) {
tk.MustQuery("select * from t").Check(testkit.Rows())
}

func TestFixControl44262(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`set tidb_partition_prune_mode='dynamic'`)
tk.MustExec(`create table t1 (a int, b int)`)
tk.MustExec(`create table t2_part (a int, b int, key(a)) partition by hash(a) partitions 4`)

testJoin := func(q, join string) {
found := false
for _, x := range tk.MustQuery(`explain ` + q).Rows() {
if strings.Contains(x[0].(string), join) {
found = true
}
}
if !found {
t.Fatal(q, join)
}
}

testJoin(`select /*+ TIDB_INLJ(t2_part@sel_2) */ * from t1 where t1.b<10 and not exists (select 1 from t2_part where t1.a=t2_part.a and t2_part.b<20)`, "HashJoin")
tk.MustQuery(`show warnings`).Sort().Check(testkit.Rows(
`Warning 1105 disable dynamic pruning due to t2_part has no global stats`,
`Warning 1815 Optimizer Hint INL_JOIN or TIDB_INLJ is inapplicable`))
tk.MustExec(`set @@tidb_opt_fix_control = "44262:ON"`)
testJoin(`select /*+ TIDB_INLJ(t2_part@sel_2) */ * from t1 where t1.b<10 and not exists (select 1 from t2_part where t1.a=t2_part.a and t2_part.b<20)`, "IndexJoin")
tk.MustQuery(`show warnings`).Sort().Check(testkit.Rows()) // no warning
}

func TestIndexJoinRangeFallback(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down
7 changes: 6 additions & 1 deletion planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4451,8 +4451,13 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as
tblStats := h.GetTableStats(tableInfo)
isDynamicEnabled := b.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled()
globalStatsReady := tblStats.IsInitialized()
allowDynamicWithoutStats := false
fixValue, ok := b.ctx.GetSessionVars().GetOptimizerFixControlValue(variable.TiDBOptFixControl44262)
if ok && variable.TiDBOptOn(fixValue) {
allowDynamicWithoutStats = true
}
// If dynamic partition prune isn't enabled or global stats is not ready, we won't enable dynamic prune mode in query
usePartitionProcessor := !isDynamicEnabled || !globalStatsReady
usePartitionProcessor := !isDynamicEnabled || (!globalStatsReady && !allowDynamicWithoutStats)

failpoint.Inject("forceDynamicPrune", func(val failpoint.Value) {
if val.(bool) {
Expand Down
19 changes: 19 additions & 0 deletions sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,25 @@ type SessionVars struct {

// EnableINLJoinInnerMultiPattern indicates whether enable multi pattern for index join inner side
EnableINLJoinInnerMultiPattern bool

// OptimizerFixControl control some details of the optimizer behavior through the tidb_opt_fix_control variable.
OptimizerFixControl map[uint64]string
}

var (
// variables below are for the optimizer fix control.

// TiDBOptFixControl44262 controls whether to allow to use dynamic-mode to access partitioning tables without global-stats (#44262).
TiDBOptFixControl44262 uint64 = 44262
)

// GetOptimizerFixControlValue returns the specified value of the optimizer fix control.
func (s *SessionVars) GetOptimizerFixControlValue(key uint64) (value string, exist bool) {
if s.OptimizerFixControl == nil {
return "", false
}
value, exist = s.OptimizerFixControl[key]
return
}

// GetNewChunkWithCapacity Attempt to request memory from the chunk pool
Expand Down
28 changes: 28 additions & 0 deletions sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -2260,6 +2260,34 @@ var defaultSysVars = []*SysVar{
return BoolToOnOff(s.EnableINLJoinInnerMultiPattern), nil
},
},
{Scope: ScopeGlobal | ScopeSession, Name: TiDBOptFixControl, Value: "", Type: TypeStr, IsHintUpdatable: true,
SetSession: func(s *SessionVars, val string) error {
newMap := make(map[uint64]string)
for _, singleFixCtrl := range strings.Split(val, ",") {
if len(singleFixCtrl) == 0 {
continue
}
colonIdx := strings.Index(singleFixCtrl, ":")
if colonIdx < 0 {
return errors.New("invalid fix control: colon not found")
}
k := strings.TrimSpace(singleFixCtrl[0:colonIdx])
v := strings.TrimSpace(singleFixCtrl[colonIdx+1:])
num, err := strconv.ParseUint(k, 10, 64)
if err != nil {
return err
}
originalV, ok := newMap[num]
if ok {
s.StmtCtx.AppendWarning(
errors.Errorf("found repeated fix control: %d:%s is overwritten with %s", num, originalV, v))
}
newMap[num] = v
}
s.OptimizerFixControl = newMap
return nil
},
},
}

// FeedbackProbability points to the FeedbackProbability in statistics package.
Expand Down
3 changes: 3 additions & 0 deletions sessionctx/variable/tidb_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,9 @@ const (

// TiDBEnableINLJoinInnerMultiPattern indicates whether enable multi pattern for inner side of inl join
TiDBEnableINLJoinInnerMultiPattern = "tidb_enable_inl_join_inner_multi_pattern"

// TiDBOptFixControl makes the user able to control some details of the optimizer behavior.
TiDBOptFixControl = "tidb_opt_fix_control"
)

// TiDB vars that have only global scope
Expand Down

0 comments on commit ede0681

Please sign in to comment.