Skip to content

Commit 45c0fb7

Browse files
qw4990ti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#48186
Signed-off-by: ti-chi-bot <[email protected]>
1 parent aa93091 commit 45c0fb7

File tree

3 files changed

+94
-7
lines changed

3 files changed

+94
-7
lines changed

pkg/planner/core/find_best_task.go

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,13 @@ func (ds *DataSource) isPointGetConvertableSchema() bool {
991991
return true
992992
}
993993

994+
// exploreEnforcedPlan determines whether to explore enforced plans for this DataSource if it has already found an unenforced plan.
995+
// See #46177 for more information.
996+
func (ds *DataSource) exploreEnforcedPlan() bool {
997+
// default value is false to keep it compatible with previous versions.
998+
return fixcontrol.GetBoolWithDefault(ds.SCtx().GetSessionVars().GetOptimizerFixControlMap(), fixcontrol.Fix46177, false)
999+
}
1000+
9941001
// findBestTask implements the PhysicalPlan interface.
9951002
// It will enumerate all the available indices and choose a plan with least cost.
9961003
func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter *PlanCounterTp, opt *physicalOptimizeOp) (t task, cntPlan int64, err error) {
@@ -1031,23 +1038,25 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter
10311038
return
10321039
}
10331040
var cnt int64
1041+
var unenforcedTask task
10341042
// If prop.CanAddEnforcer is true, the prop.SortItems need to be set nil for ds.findBestTask.
10351043
// Before function return, reset it for enforcing task prop and storing map<prop,task>.
10361044
oldProp := prop.CloneEssentialFields()
10371045
if prop.CanAddEnforcer {
10381046
// First, get the bestTask without enforced prop
10391047
prop.CanAddEnforcer = false
1040-
t, cnt, err = ds.findBestTask(prop, planCounter, opt)
1048+
unenforcedTask, cnt, err = ds.findBestTask(prop, planCounter, opt)
10411049
if err != nil {
10421050
return nil, 0, err
10431051
}
1044-
prop.CanAddEnforcer = true
1045-
if t != invalidTask {
1046-
ds.storeTask(prop, t)
1047-
cntPlan = cnt
1048-
return
1052+
if !unenforcedTask.invalid() && !ds.exploreEnforcedPlan() {
1053+
ds.storeTask(prop, unenforcedTask)
1054+
return unenforcedTask, cnt, nil
10491055
}
1050-
// Next, get the bestTask with enforced prop
1056+
1057+
// Then, explore the bestTask with enforced prop
1058+
prop.CanAddEnforcer = true
1059+
cntPlan += cnt
10511060
prop.SortItems = []property.SortItem{}
10521061
prop.MPPPartitionTp = property.AnyType
10531062
} else if prop.MPPPartitionTp != property.AnyType {
@@ -1062,6 +1071,18 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter
10621071
t = enforceProperty(prop, t, ds.Plan.SCtx())
10631072
prop.CanAddEnforcer = true
10641073
}
1074+
1075+
if unenforcedTask != nil && !unenforcedTask.invalid() {
1076+
curIsBest, cerr := compareTaskCost(ds.SCtx(), unenforcedTask, t, opt)
1077+
if cerr != nil {
1078+
err = cerr
1079+
return
1080+
}
1081+
if curIsBest {
1082+
t = unenforcedTask
1083+
}
1084+
}
1085+
10651086
ds.storeTask(prop, t)
10661087
if ds.SampleInfo != nil && !t.invalid() {
10671088
if _, ok := t.plan().(*PhysicalTableSample); !ok {

pkg/planner/core/integration_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,6 +2529,65 @@ func TestIssue46298(t *testing.T) {
25292529
tk.MustQuery("select *, first_value(v) over (partition by p order by o range between 3.1 preceding and 2.9 following) as a from test.first_range;")
25302530
}
25312531

2532+
<<<<<<< HEAD
2533+
=======
2534+
func TestIssue45044(t *testing.T) {
2535+
store := testkit.CreateMockStore(t)
2536+
tk := testkit.NewTestKit(t, store)
2537+
tk.MustExec(`use test`)
2538+
tk.MustExec(`set tidb_enable_ordered_result_mode = on`)
2539+
tk.MustExec(`create table t1(c1 int)`)
2540+
tk.MustQuery(`select * from t1 group by t1.c1 having count(1) > 1 order by count(1) limit 10`).Check(testkit.Rows()) // no error
2541+
}
2542+
2543+
func TestIssue46177(t *testing.T) {
2544+
store := testkit.CreateMockStore(t)
2545+
tk := testkit.NewTestKit(t, store)
2546+
tk.MustExec(`use test`)
2547+
tk.MustExec(` CREATE TABLE sbtest (
2548+
id int(10) unsigned NOT NULL AUTO_INCREMENT,
2549+
k int(10) unsigned NOT NULL DEFAULT '0',
2550+
c char(120) NOT NULL DEFAULT '',
2551+
pad char(60) NOT NULL DEFAULT '',
2552+
PRIMARY KEY (id) /*T![clustered_index] CLUSTERED */,
2553+
KEY k (k)
2554+
)`)
2555+
2556+
// cannot choose the best plan with RangeScan.
2557+
tk.MustExec(`set @@tidb_opt_fix_control = '46177:off'`)
2558+
tk.MustQuery(`explain format='brief' select row_number() over(order by a.k) from (select * from sbtest where id<10) a`).Check(testkit.Rows(
2559+
`Projection 10.00 root Column#6->Column#7`,
2560+
`└─Window 10.00 root row_number()->Column#6 over(order by test.sbtest.k rows between current row and current row)`,
2561+
` └─IndexReader 10.00 root index:Selection`,
2562+
` └─Selection 10.00 cop[tikv] lt(test.sbtest.id, 10)`,
2563+
` └─IndexFullScan 10000.00 cop[tikv] table:sbtest, index:k(k) keep order:true, stats:pseudo`))
2564+
2565+
tk.MustExec(`set @@tidb_opt_fix_control = '46177:on'`)
2566+
tk.MustQuery(`explain format='brief' select row_number() over(order by a.k) from (select * from sbtest where id<10) a`).Check(testkit.Rows(
2567+
`Projection 10.00 root Column#6->Column#7`,
2568+
`└─Window 10.00 root row_number()->Column#6 over(order by test.sbtest.k rows between current row and current row)`,
2569+
` └─Sort 10.00 root test.sbtest.k`,
2570+
` └─TableReader 10.00 root data:TableRangeScan`,
2571+
` └─TableRangeScan 10.00 cop[tikv] table:sbtest range:[0,10), keep order:false, stats:pseudo`))
2572+
2573+
// cannot choose the range scan plan.
2574+
tk.MustExec(`set @@tidb_opt_fix_control = '46177:off'`)
2575+
tk.MustQuery(`explain format='brief' select /*+ stream_agg() */ count(1) from sbtest where id<1 group by k`).Check(testkit.Rows(
2576+
`StreamAgg 1.00 root group by:test.sbtest.k, funcs:count(Column#6)->Column#5`,
2577+
`└─IndexReader 1.00 root index:StreamAgg`,
2578+
` └─StreamAgg 1.00 cop[tikv] group by:test.sbtest.k, funcs:count(1)->Column#6`,
2579+
` └─Selection 1.00 cop[tikv] lt(test.sbtest.id, 1)`,
2580+
` └─IndexFullScan 10000.00 cop[tikv] table:sbtest, index:k(k) keep order:true, stats:pseudo`))
2581+
2582+
tk.MustExec(`set @@tidb_opt_fix_control = '46177:on'`)
2583+
tk.MustQuery(`explain format='brief' select /*+ stream_agg() */ count(1) from sbtest where id<1 group by k`).Check(testkit.Rows(
2584+
`StreamAgg 1.00 root group by:test.sbtest.k, funcs:count(1)->Column#5`,
2585+
`└─Sort 1.00 root test.sbtest.k`,
2586+
` └─TableReader 1.00 root data:TableRangeScan`,
2587+
` └─TableRangeScan 1.00 cop[tikv] table:sbtest range:[0,1), keep order:false, stats:pseudo`))
2588+
}
2589+
2590+
>>>>>>> 0172ba0a1ab (planner: fix the issue that the optimizer terminates the optimization process for `DataSource` too early (#48186))
25322591
// https://github.com/pingcap/tidb/issues/41458
25332592
func TestIssue41458(t *testing.T) {
25342593
store := testkit.CreateMockStore(t)

pkg/planner/util/fixcontrol/get.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ const (
3434
Fix44855 uint64 = 44855
3535
// Fix45132 controls whether to use access range row count to determine access path on the Skyline pruning.
3636
Fix45132 uint64 = 45132
37+
<<<<<<< HEAD
38+
=======
39+
// Fix45798 controls whether to cache plans that access generated columns.
40+
Fix45798 uint64 = 45798
41+
// Fix46177 controls whether to explore enforced plans for DataSource if it has already found an unenforced plan.
42+
Fix46177 uint64 = 46177
43+
>>>>>>> 0172ba0a1ab (planner: fix the issue that the optimizer terminates the optimization process for `DataSource` too early (#48186))
3744
)
3845

3946
// GetStr fetches the given key from the fix control map as a string type.

0 commit comments

Comments
 (0)