Skip to content

Commit 2a74539

Browse files
planner: extend order ratio to joins (#61687)
close #62034
1 parent 5fe53c7 commit 2a74539

File tree

5 files changed

+60
-7
lines changed

5 files changed

+60
-7
lines changed

pkg/bindinfo/testdata/binding_auto_suite_out.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@
172172
"Fixes": "[52869]"
173173
},
174174
{
175-
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_index_join_cost_factor tidb_opt_index_reader_cost_factor tidb_opt_index_scan_cost_factor tidb_opt_merge_join_cost_factor tidb_opt_prefer_range_scan]",
175+
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_index_join_cost_factor tidb_opt_index_reader_cost_factor tidb_opt_index_scan_cost_factor tidb_opt_merge_join_cost_factor tidb_opt_ordering_index_selectivity_ratio tidb_opt_prefer_range_scan]",
176176
"Fixes": "[44855 45132 52869]"
177177
},
178178
{
179-
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_index_join_cost_factor tidb_opt_index_reader_cost_factor tidb_opt_index_scan_cost_factor tidb_opt_merge_join_cost_factor tidb_opt_prefer_range_scan]",
179+
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_index_join_cost_factor tidb_opt_index_reader_cost_factor tidb_opt_index_scan_cost_factor tidb_opt_merge_join_cost_factor tidb_opt_ordering_index_selectivity_ratio tidb_opt_prefer_range_scan]",
180180
"Fixes": "[44855 45132 52869]"
181181
},
182182
{
183-
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_prefer_range_scan tidb_opt_table_full_scan_cost_factor tidb_opt_table_reader_cost_factor]",
183+
"Vars": "[tidb_opt_hash_join_cost_factor tidb_opt_ordering_index_selectivity_ratio tidb_opt_prefer_range_scan tidb_opt_table_full_scan_cost_factor tidb_opt_table_reader_cost_factor]",
184184
"Fixes": "[52869]"
185185
}
186186
]

pkg/planner/cardinality/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ go_test(
6060
data = glob(["testdata/**"]),
6161
embed = [":cardinality"],
6262
flaky = True,
63-
shard_count = 32,
63+
shard_count = 33,
6464
deps = [
6565
"//pkg/config",
6666
"//pkg/domain",

pkg/planner/cardinality/selectivity_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"os"
2222
"runtime/pprof"
2323
"slices"
24+
"strconv"
2425
"strings"
2526
"testing"
2627
"time"
@@ -1286,6 +1287,45 @@ func TestOrderingIdxSelectivityRatio(t *testing.T) {
12861287
}
12871288
}
12881289

1290+
func TestOrderingIdxSelectivityRatioForJoin(t *testing.T) {
1291+
store, dom := testkit.CreateMockStoreAndDomain(t)
1292+
testKit := testkit.NewTestKit(t, store)
1293+
1294+
testKit.MustExec("use test")
1295+
testKit.MustExec("drop table if exists t")
1296+
testKit.MustExec("create table t(a int, b int, c int, index ibc(b, c))")
1297+
testKit.MustExec("insert into t values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6), (7,7,7), (8,8,8), (9,9,9), (10,10,10)")
1298+
testKit.MustExec("insert into t select a,b,c from t")
1299+
testKit.MustExec("analyze table t")
1300+
h := dom.StatsHandle()
1301+
require.Nil(t, h.DumpStatsDeltaToKV(true))
1302+
1303+
// Discourage merge join and hash join to encourage index join, and discourage topn to encourage limit.
1304+
testKit.MustExec("set @@session.tidb_opt_merge_join_cost_factor = 1000")
1305+
testKit.MustExec("set @@session.tidb_opt_hash_join_cost_factor = 1000")
1306+
testKit.MustExec("set @@session.tidb_opt_topn_cost_factor = 1000")
1307+
// Disable idx_selectivity_ratio using -1 and 0 - both should have no effect.
1308+
testKit.MustExec("set @@session.tidb_opt_ordering_index_selectivity_ratio = -1")
1309+
rs := testKit.MustQuery("explain format=verbose select t1.* from t t1 use index (ibc) join t t2 on t1.b=t2.b where t2.c=5 order by t1.b limit 2").Rows()
1310+
planCost1, err1 := strconv.ParseFloat(rs[0][2].(string), 64)
1311+
require.Nil(t, err1)
1312+
testKit.MustExec("set @@session.tidb_opt_ordering_index_selectivity_ratio = 0")
1313+
rs = testKit.MustQuery("explain format=verbose select t1.* from t t1 use index (ibc) join t t2 on t1.b=t2.b where t2.c=5 order by t1.b limit 2").Rows()
1314+
planCost2, err2 := strconv.ParseFloat(rs[0][2].(string), 64)
1315+
require.Nil(t, err2)
1316+
require.Equal(t, planCost1, planCost2)
1317+
// Increasing the ratio should increase the cost of index join, so the plan cost should increase.
1318+
testKit.MustExec("set @@session.tidb_opt_ordering_index_selectivity_ratio = 0.5")
1319+
rs = testKit.MustQuery("explain format=verbose select t1.* from t t1 use index (ibc) join t t2 on t1.b=t2.b where t2.c=5 order by t1.b limit 2").Rows()
1320+
planCost3, err3 := strconv.ParseFloat(rs[0][2].(string), 64)
1321+
require.Nil(t, err3)
1322+
require.Less(t, planCost2, planCost3)
1323+
testKit.MustExec("set @@session.tidb_opt_ordering_index_selectivity_ratio = 1")
1324+
rs = testKit.MustQuery("explain format=verbose select t1.* from t t1 use index (ibc) join t t2 on t1.b=t2.b where t2.c=5 order by t1.b limit 2").Rows()
1325+
planCost4, err4 := strconv.ParseFloat(rs[0][2].(string), 64)
1326+
require.Nil(t, err4)
1327+
require.Less(t, planCost3, planCost4)
1328+
}
12891329
func TestCrossValidationSelectivity(t *testing.T) {
12901330
store, dom := testkit.CreateMockStoreAndDomain(t)
12911331
tk := testkit.NewTestKit(t, store)

pkg/planner/core/exhaust_physical_plans.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/pingcap/tidb/pkg/planner/property"
3636
"github.com/pingcap/tidb/pkg/planner/util"
3737
"github.com/pingcap/tidb/pkg/planner/util/fixcontrol"
38+
"github.com/pingcap/tidb/pkg/sessionctx/vardef"
3839
"github.com/pingcap/tidb/pkg/statistics"
3940
"github.com/pingcap/tidb/pkg/types"
4041
"github.com/pingcap/tidb/pkg/util/dbterror/plannererrors"
@@ -581,10 +582,21 @@ func constructIndexJoinStatic(
581582
chReqProps := make([]*property.PhysicalProperty, 2)
582583
// outer side expected cnt will be amplified by the prop.ExpectedCnt / p.StatsInfo().RowCount with same ratio.
583584
chReqProps[outerIdx] = &property.PhysicalProperty{TaskTp: property.RootTaskType, ExpectedCnt: math.MaxFloat64, SortItems: prop.SortItems, CTEProducerStatus: prop.CTEProducerStatus}
584-
if prop.ExpectedCnt < p.StatsInfo().RowCount {
585-
expCntScale := prop.ExpectedCnt / p.StatsInfo().RowCount
586-
chReqProps[outerIdx].ExpectedCnt = p.Children()[outerIdx].StatsInfo().RowCount * expCntScale
585+
orderRatio := p.SCtx().GetSessionVars().OptOrderingIdxSelRatio
586+
// Record the variable usage for explain explore.
587+
p.SCtx().GetSessionVars().RecordRelevantOptVar(vardef.TiDBOptOrderingIdxSelRatio)
588+
outerRowCount := p.Children()[outerIdx].StatsInfo().RowCount
589+
estimatedRowCount := p.StatsInfo().RowCount
590+
if (prop.ExpectedCnt < estimatedRowCount) ||
591+
(orderRatio > 0 && outerRowCount > estimatedRowCount && prop.ExpectedCnt < outerRowCount && estimatedRowCount > 0) {
592+
// Apply the orderRatio to recognize that a large outer table scan may
593+
// read additional rows before the inner table reaches the limit values
594+
rowsToMeetFirst := max(0.0, (outerRowCount-estimatedRowCount)*orderRatio)
595+
expCntScale := prop.ExpectedCnt / estimatedRowCount
596+
expectedCnt := (outerRowCount * expCntScale) + rowsToMeetFirst
597+
chReqProps[outerIdx].ExpectedCnt = expectedCnt
587598
}
599+
588600
// inner side should pass down the indexJoinProp, which contains the runtime constant inner key, which is used to build the underlying index/pk range.
589601
chReqProps[1-outerIdx] = &property.PhysicalProperty{TaskTp: property.RootTaskType, ExpectedCnt: math.MaxFloat64, CTEProducerStatus: prop.CTEProducerStatus, IndexJoinProp: indexJoinProp}
590602

pkg/sessionctx/variable/session.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,6 +2291,7 @@ func NewSessionVars(hctx HookContext) *SessionVars {
22912291
EnableWindowFunction: vardef.DefEnableWindowFunction,
22922292
CostModelVersion: vardef.DefTiDBCostModelVer,
22932293
OptimizerEnableNAAJ: vardef.DefTiDBEnableNAAJ,
2294+
OptOrderingIdxSelRatio: vardef.DefTiDBOptOrderingIdxSelRatio,
22942295
}
22952296
vars.status.Store(uint32(mysql.ServerStatusAutocommit))
22962297
vars.StmtCtx.ResourceGroupName = resourcegroup.DefaultResourceGroupName

0 commit comments

Comments
 (0)