Skip to content

Commit 4e51ae7

Browse files
hawkingreiwinoros
authored andcommitted
planner: predicate simplification when to push down predicate with join (pingcap#61316)
close pingcap#45785
1 parent e99d482 commit 4e51ae7

File tree

7 files changed

+48
-47
lines changed

7 files changed

+48
-47
lines changed

pkg/planner/core/casetest/join/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ go_test(
88
"main_test.go",
99
],
1010
flaky = True,
11+
shard_count = 3,
1112
deps = [
1213
"//pkg/config",
1314
"//pkg/testkit",

pkg/planner/core/casetest/join/join_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,21 @@ func TestJoinWithNullEQ(t *testing.T) {
142142
FROM tt0) as subQuery1 ON ((subQuery1.col_0) = (tt1.c0))
143143
INNER JOIN tt0 ON (subQuery1.col_0 <=> tt0.c0);`).Check(testkit.Rows())
144144
}
145+
146+
func TestJoinSimplifyCondition(t *testing.T) {
147+
store := testkit.CreateMockStore(t)
148+
tk := testkit.NewTestKit(t, store)
149+
tk.MustExec("use test;")
150+
tk.MustExec(`CREATE TABLE t1 (a int(11) DEFAULT NULL,b int(11) DEFAULT NULL,c int(11) DEFAULT NULL,KEY idx_a (a));`)
151+
tk.MustExec(`CREATE TABLE t2 (a int(11) DEFAULT NULL,b int(11) DEFAULT NULL,c int(11) DEFAULT NULL,KEY idx_a (a));`)
152+
tk.MustQuery(`explain format='brief' select * from t1,t2 where t1.a=t2.a and t1.b = 1 or 1=2;`).
153+
Check(testkit.Rows(
154+
"IndexHashJoin 12.49 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)",
155+
"├─TableReader(Build) 9.99 root data:Selection",
156+
"│ └─Selection 9.99 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))",
157+
"│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
158+
"└─IndexLookUp(Probe) 12.49 root ",
159+
" ├─Selection(Build) 12.49 cop[tikv] not(isnull(test.t2.a))",
160+
" │ └─IndexRangeScan 12.50 cop[tikv] table:t2, index:idx_a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo",
161+
" └─TableRowIDScan(Probe) 12.49 cop[tikv] table:t2 keep order:false, stats:pseudo"))
162+
}

pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2457,7 +2457,7 @@
24572457
},
24582458
{
24592459
"SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a = all(select t2.b from t t2)",
2460-
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))->HashAgg->Sel([or(and(le(Column#26, 1), if(ne(Column#27, 0), <nil>, 1)), or(eq(Column#28, 0), 0))])}",
2460+
"Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))->HashAgg->Sel([or(and(le(Column#26, 1), if(ne(Column#27, 0), <nil>, 1)), eq(Column#28, 0))])}",
24612461
"Warning": ""
24622462
},
24632463
{

pkg/planner/core/casetest/rule/testdata/outer2inner_out.json

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,12 @@
422422
{
423423
"SQL": "select * from t2 left outer join t1 on a1=a2 where true OR b1 = 5; -- negative case with OR and one branch is TRUE",
424424
"Plan": [
425-
"Selection 9990.00 root or(1, eq(test.t1.b1, 5))",
426-
"└─HashJoin 12487.50 root left outer join, equal:[eq(test.t2.a2, test.t1.a1)]",
427-
" ├─TableReader(Build) 9990.00 root data:Selection",
428-
" │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a1))",
429-
" │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
430-
" └─TableReader(Probe) 10000.00 root data:TableFullScan",
431-
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
425+
"HashJoin 12487.50 root left outer join, equal:[eq(test.t2.a2, test.t1.a1)]",
426+
"├─TableReader(Build) 9990.00 root data:Selection",
427+
"│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a1))",
428+
"│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
429+
"└─TableReader(Probe) 10000.00 root data:TableFullScan",
430+
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
432431
]
433432
},
434433
{
@@ -636,18 +635,6 @@
636635
" └─TableReader(Probe) 10000.00 root data:TableFullScan",
637636
" └─TableFullScan 10000.00 cop[tikv] table:t0 keep order:false, stats:pseudo"
638637
]
639-
},
640-
{
641-
"SQL": "select * from t1 left outer join t2 on a1=a2 where not (b2 is NOT NULL AND c2 = 5) -- NOT case ",
642-
"Plan": [
643-
"Selection 9990.00 root not(and(not(isnull(test.t2.b2)), eq(test.t2.c2, 5)))",
644-
"└─HashJoin 12487.50 root left outer join, equal:[eq(test.t1.a1, test.t2.a2)]",
645-
" ├─TableReader(Build) 9990.00 root data:Selection",
646-
" │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a2))",
647-
" │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
648-
" └─TableReader(Probe) 10000.00 root data:TableFullScan",
649-
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
650-
]
651638
}
652639
]
653640
},

pkg/planner/core/operator/logicalop/logical_join.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ func (p *LogicalJoin) ReplaceExprColumns(replace map[string]*expression.Column)
198198

199199
// PredicatePushDown implements the base.LogicalPlan.<1st> interface.
200200
func (p *LogicalJoin) PredicatePushDown(predicates []expression.Expression, opt *optimizetrace.LogicalOptimizeOp) (ret []expression.Expression, retPlan base.LogicalPlan) {
201+
predicates = utilfuncp.ApplyPredicateSimplification(p.SCtx(), predicates)
201202
var equalCond []*expression.ScalarFunction
202203
var leftPushCond, rightPushCond, otherCond, leftCond, rightCond []expression.Expression
203204
switch p.JoinType {

tests/integrationtest/r/executor/merge_join.result

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,13 @@ select /*+ TIDB_SMJ(t) */ * from t right outer join t1 on t.c1 = t1.c1 where t.c
4747
c1 c2 c1 c2
4848
explain format = 'brief' select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false;
4949
id estRows task access object operator info
50-
MergeJoin 12.50 root inner join, left key:executor__merge_join.t.c1, right key:executor__merge_join.t1.c1
51-
├─Sort(Build) 10.00 root executor__merge_join.t1.c1
52-
│ └─TableReader 10.00 root data:Selection
53-
│ └─Selection 10.00 cop[tikv] eq(executor__merge_join.t1.c1, 3), not(isnull(executor__merge_join.t1.c1))
54-
│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
55-
└─Sort(Probe) 10.00 root executor__merge_join.t.c1
56-
└─TableReader 10.00 root data:Selection
57-
└─Selection 10.00 cop[tikv] eq(executor__merge_join.t.c1, 3), not(isnull(executor__merge_join.t.c1))
58-
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
50+
MergeJoin 100.00 root inner join
51+
├─TableReader(Build) 10.00 root data:Selection
52+
│ └─Selection 10.00 cop[tikv] eq(executor__merge_join.t1.c1, 3)
53+
│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
54+
└─TableReader(Probe) 10.00 root data:Selection
55+
└─Selection 10.00 cop[tikv] eq(executor__merge_join.t.c1, 3)
56+
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
5957
select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false;
6058
c1 c2 c1 c2
6159
explain format = 'brief' select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 and t.c1 != 1 order by t1.c1;
@@ -320,18 +318,13 @@ select /*+ TIDB_SMJ(t) */ * from t right outer join t1 on t.c1 = t1.c1 where t.c
320318
c1 c2 c1 c2
321319
explain format = 'brief' select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false;
322320
id estRows task access object operator info
323-
Shuffle 12.50 root execution info: concurrency:4, data sources:[TableReader TableReader]
324-
└─MergeJoin 12.50 root inner join, left key:executor__merge_join.t.c1, right key:executor__merge_join.t1.c1
325-
├─Sort(Build) 10.00 root executor__merge_join.t1.c1
326-
│ └─ShuffleReceiver 10.00 root
327-
│ └─TableReader 10.00 root data:Selection
328-
│ └─Selection 10.00 cop[tikv] eq(executor__merge_join.t1.c1, 3), not(isnull(executor__merge_join.t1.c1))
329-
│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
330-
└─Sort(Probe) 10.00 root executor__merge_join.t.c1
331-
└─ShuffleReceiver 10.00 root
332-
└─TableReader 10.00 root data:Selection
333-
└─Selection 10.00 cop[tikv] eq(executor__merge_join.t.c1, 3), not(isnull(executor__merge_join.t.c1))
334-
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
321+
MergeJoin 100.00 root inner join
322+
├─TableReader(Build) 10.00 root data:Selection
323+
│ └─Selection 10.00 cop[tikv] eq(executor__merge_join.t1.c1, 3)
324+
│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
325+
└─TableReader(Probe) 10.00 root data:Selection
326+
└─Selection 10.00 cop[tikv] eq(executor__merge_join.t.c1, 3)
327+
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
335328
select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false;
336329
c1 c2 c1 c2
337330
explain format = 'brief' select /*+ TIDB_SMJ(t) */ * from t left outer join t1 on t.c1 = t1.c1 and t.c1 != 1 order by t1.c1;

tests/integrationtest/r/planner/core/casetest/predicate_simplification.result

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,14 @@ LIMIT
176176
240;
177177
id estRows task access object operator info
178178
Projection 41.67 root planner__core__casetest__predicate_simplification.dt.a, planner__core__casetest__predicate_simplification.dt.pk, planner__core__casetest__predicate_simplification.dt.b, planner__core__casetest__predicate_simplification.dt.c
179-
└─IndexHashJoin 41.67 root left outer join, inner:TableReader, outer key:planner__core__casetest__predicate_simplification.it.pk, inner key:planner__core__casetest__predicate_simplification.dt.pk, equal cond:eq(planner__core__casetest__predicate_simplification.it.pk, planner__core__casetest__predicate_simplification.dt.pk), other cond:or(gt(planner__core__casetest__predicate_simplification.it.a, "a"), and(eq(planner__core__casetest__predicate_simplification.it.a, "a"), gt(planner__core__casetest__predicate_simplification.dt.pk, 1)))
179+
└─IndexJoin 41.67 root left outer join, inner:TableReader, outer key:planner__core__casetest__predicate_simplification.it.pk, inner key:planner__core__casetest__predicate_simplification.dt.pk, equal cond:eq(planner__core__casetest__predicate_simplification.it.pk, planner__core__casetest__predicate_simplification.dt.pk)
180180
├─Limit(Build) 33.33 root offset:0, count:240
181181
│ └─IndexReader 33.33 root index:Limit
182182
│ └─Limit 33.33 cop[tikv] offset:0, count:240
183183
│ └─IndexRangeScan 33.33 cop[tikv] table:it, index:f(a, pk) range:("a" 1,"a" +inf], keep order:true, stats:pseudo
184-
└─TableReader(Probe) 33.33 root data:TableRangeScan
185-
└─TableRangeScan 33.33 cop[tikv] table:dt range: decided by [planner__core__casetest__predicate_simplification.it.pk], keep order:false, stats:pseudo
184+
└─TableReader(Probe) 11.11 root data:Selection
185+
└─Selection 11.11 cop[tikv] gt(planner__core__casetest__predicate_simplification.dt.pk, 1)
186+
└─TableRangeScan 33.33 cop[tikv] table:dt range: decided by [planner__core__casetest__predicate_simplification.it.pk], keep order:false, stats:pseudo
186187
explain format='brief' SELECT * FROM
187188
(
188189
SELECT
@@ -349,7 +350,7 @@ SELECT 1 FROM t1 AS tab WHERE a1 > 5 OR (EXISTS(SELECT 1 FROM t2 WHERE a2 = a1 )
349350
id estRows task access object operator info
350351
Projection 8000.00 root 1->Column#10
351352
└─Selection 8000.00 root or(gt(planner__core__casetest__predicate_simplification.t1.a1, 5), Column#9)
352-
└─HashJoin 10000.00 root left outer semi join, left side:TableReader, equal:[eq(planner__core__casetest__predicate_simplification.t1.a1, planner__core__casetest__predicate_simplification.t2.a2)]
353+
└─HashJoin 10000.00 root left outer semi join, equal:[eq(planner__core__casetest__predicate_simplification.t1.a1, planner__core__casetest__predicate_simplification.t2.a2)]
353354
├─TableReader(Build) 10000.00 root data:TableFullScan
354355
│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
355356
└─TableReader(Probe) 10000.00 root data:TableFullScan
@@ -404,8 +405,8 @@ SELECT 1 FROM t1 AS tab WHERE 1 = 1 OR (EXISTS(SELECT 1 FROM t2 WHERE a2 = a1));
404405
id estRows task access object operator info
405406
Union 18000.00 root
406407
├─Projection 8000.00 root 1->Column#21
407-
│ └─Selection 8000.00 root or(0, Column#9)
408-
│ └─HashJoin 10000.00 root left outer semi join, left side:TableReader, equal:[eq(planner__core__casetest__predicate_simplification.t1.a1, planner__core__casetest__predicate_simplification.t2.a2)]
408+
│ └─Selection 8000.00 root Column#9
409+
│ └─HashJoin 10000.00 root left outer semi join, equal:[eq(planner__core__casetest__predicate_simplification.t1.a1, planner__core__casetest__predicate_simplification.t2.a2)]
409410
│ ├─TableReader(Build) 10000.00 root data:TableFullScan
410411
│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
411412
│ └─TableReader(Probe) 10000.00 root data:TableFullScan

0 commit comments

Comments
 (0)