Skip to content

Commit 01648fe

Browse files
winorosti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#59933
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 9325eee commit 01648fe

File tree

3 files changed

+187
-1
lines changed

3 files changed

+187
-1
lines changed

pkg/planner/core/exhaust_physical_plans.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ func (p *LogicalJoin) GetMergeJoin(prop *property.PhysicalProperty, schema *expr
181181
offsets := getMaxSortPrefix(lhsChildProperty, leftJoinKeys)
182182
// If not all equal conditions hit properties. We ban merge join heuristically. Because in this case, merge join
183183
// may get a very low performance. In executor, executes join results before other conditions filter it.
184-
if len(offsets) < len(leftJoinKeys) {
184+
// And skip the cartesian join case, unless we force to use merge join.
185+
if len(offsets) < len(leftJoinKeys) || len(leftJoinKeys) == 0 {
185186
continue
186187
}
187188

@@ -192,8 +193,14 @@ func (p *LogicalJoin) GetMergeJoin(prop *property.PhysicalProperty, schema *expr
192193
newIsNullEQ = append(newIsNullEQ, isNullEQ[offset])
193194
}
194195

196+
<<<<<<< HEAD
195197
prefixLen := findMaxPrefixLen(p.rightProperties, rightKeys)
196198
if prefixLen == 0 {
199+
=======
200+
prefixLen := findMaxPrefixLen(p.RightProperties, rightKeys)
201+
// right side should also be full match.
202+
if prefixLen < len(offsets) || prefixLen == 0 {
203+
>>>>>>> 163c4bed8fa (planner: don't choose merge join unless there's hint or join key fully matched (#59933))
197204
continue
198205
}
199206

tests/integrationtest/r/planner/core/issuetest/planner_issue.result

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ JOIN tceb7972c ON tceb7972c.col_19 = t61a85298.col_71
681681
WHERE 16739493649928310215 MEMBER OF (derived_table.col_60767)
682682
OR NOT (JSON_CONTAINS(derived_table.col_60767, '6019730272580550835'));
683683
id estRows task access object operator info
684+
<<<<<<< HEAD
684685
Projection_12 10000.00 root 1->Column#19
685686
└─HashJoin_13 10000.00 root inner join, equal:[eq(planner__core__issuetest__planner_issue.tceb7972c.col_19, Column#20)]
686687
├─Projection_19(Build) 10000.00 root cast(planner__core__issuetest__planner_issue.t61a85298.col_71, double BINARY)->Column#20
@@ -691,3 +692,111 @@ Projection_12 10000.00 root 1->Column#19
691692
└─Selection_17 8000.00 cop[tikv] or(json_memberof(cast(16739493649928310215, json BINARY), planner__core__issuetest__planner_issue.tceb7972c.col_17), not(istrue_with_null(json_contains(planner__core__issuetest__planner_issue.tceb7972c.col_17, cast("6019730272580550835", json BINARY)))))
692693
└─TableFullScan_16 10000.00 cop[tikv] table:tceb7972c keep order:false, stats:pseudo
693694
set @@tidb_enable_global_index=0;
695+
=======
696+
Projection_11 6.00 root 1->Column#18
697+
└─HashJoin_13 6.00 root inner join, equal:[eq(test.tceb7972c.col_19, Column#19)]
698+
├─TableReader_16(Build) 4.80 root partition:all data:Selection_15
699+
│ └─Selection_15 4.80 cop[tikv] or(json_memberof(cast(16739493649928310215, json BINARY), test.tceb7972c.col_17), not(istrue_with_null(json_contains(test.tceb7972c.col_17, cast("6019730272580550835", json BINARY)))))
700+
│ └─TableFullScan_14 6.00 cop[tikv] table:tceb7972c keep order:false, stats:partial[col_17:missing]
701+
└─Projection_17(Probe) 10000.00 root cast(test.t61a85298.col_71, double BINARY)->Column#19
702+
└─TableReader_19 10000.00 root data:TableFullScan_18
703+
└─TableFullScan_18 10000.00 cop[tikv] table:t61a85298 keep order:false, stats:pseudo
704+
drop table if exists t0, t1;
705+
CREATE TABLE t0(c0 int);
706+
CREATE TABLE t1(c0 int);
707+
SELECT t0.c0, t1.c0 FROM t0 NATURAL JOIN t1 WHERE '1' AND (t0.c0 IN (SELECT c0 FROM t0));
708+
c0 c0
709+
drop table if exists t1, t2, t3, t4;
710+
CREATE TABLE t1 (a int, b int, c int);
711+
CREATE TABLE t2 (a int, b int, c int);
712+
CREATE TABLE t3 (a int, b int, c int);
713+
CREATE TABLE t4 (a int, b int, c int);
714+
INSERT INTO t1 VALUES (1,3,0), (2,2,0), (3,2,0);
715+
INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
716+
INSERT INTO t3 VALUES (1,2,0), (2,2,0);
717+
INSERT INTO t4 VALUES (3,2,0), (4,2,0);
718+
CREATE INDEX idx_b ON t2(b);
719+
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
720+
FROM (t3,t4)
721+
LEFT JOIN
722+
(t1,t2)
723+
ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b order by 1, 2, 3, 4, 5;
724+
a b a b a b
725+
NULL NULL 2 2 3 2
726+
NULL NULL 2 2 4 2
727+
4 2 1 2 3 2
728+
4 2 1 2 3 2
729+
4 2 1 2 3 2
730+
4 2 1 2 4 2
731+
4 2 1 2 4 2
732+
4 2 1 2 4 2
733+
show warnings;
734+
Level Code Message
735+
drop table if exists t1, t2, t3, t4;
736+
drop table if exists t0, v0;
737+
drop view if exists v0;
738+
CREATE TABLE t0(c0 INTEGER);
739+
CREATE VIEW v0(c0) AS SELECT 'a' FROM t0 WHERE (CASE t0.c0 WHEN t0.c0 THEN false END );
740+
SELECT t0.c0 FROM v0, t0 WHERE RAND();
741+
c0
742+
drop table if exists tl6e913fb9;
743+
CREATE TABLE `tl6e913fb9` (
744+
`col_36` varchar(175) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'asMF',
745+
KEY `idx_35_5` (`col_36`(1)),
746+
PRIMARY KEY (`col_36`) /*T![clustered_index] NONCLUSTERED */,
747+
KEY `idx_65` (`col_36`(5))
748+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
749+
with cte_192 ( col_1101,col_1102,col_1103,col_1104 ) AS ( select /*+ use_index_merge( tl6e913fb9 ) */ replace( tl6e913fb9.col_36 , tl6e913fb9.col_36 , tl6e913fb9.col_36 ) as r0 , space( 0 ) as r1 , min( distinct tl6e913fb9.col_36 ) as r2 , count( distinct tl6e913fb9.col_36 ) as r3 from tl6e913fb9 where tl6e913fb9.col_36 between 'n92ok$B%W#UU%O' and '()c=KVQ=T%-vzGJ' and tl6e913fb9.col_36 in ( 'T+kf' ,'Lvluod2H' ,'3#Omx@pC^fFkeH' ,'=b$z' ) group by tl6e913fb9.col_36 having tl6e913fb9.col_36 = 'xjV@' or IsNull( tl6e913fb9.col_36 ) ) ( select 1,col_1101,col_1102,col_1103,col_1104 from cte_192 where not( IsNull( cte_192.col_1102 ) ) order by 1,2,3,4,5 limit 72850972 );
750+
1 col_1101 col_1102 col_1103 col_1104
751+
drop table if exists t;
752+
create table t (id int unique key, c int);
753+
insert into t values (1, 10);
754+
insert into t values (2, 20);
755+
insert into t values (3, 30);
756+
select _tidb_rowid from t where id in (1, 2, 3);
757+
_tidb_rowid
758+
1
759+
2
760+
3
761+
drop table if exists t, t1;
762+
create table t(a int);
763+
create table t1(a int primary key, b int, index idx(b));
764+
insert into t values(1), (2), (123);
765+
insert into t1 values(2, 123), (123, 2);
766+
set tidb_opt_fix_control='44855:on';
767+
explain select /*+ inl_join(t1), use_index(t1, idx) */ * from t join t1 on t.a = t1.a and t1.b = 123;
768+
id estRows task access object operator info
769+
Projection_9 12.50 root test.t.a, test.t1.a, test.t1.b
770+
└─IndexJoin_12 12.50 root inner join, inner:IndexReader_11, outer key:test.t.a, inner key:test.t1.a, equal cond:eq(test.t.a, test.t1.a)
771+
├─TableReader_20(Build) 9990.00 root data:Selection_19
772+
│ └─Selection_19 9990.00 cop[tikv] not(isnull(test.t.a))
773+
│ └─TableFullScan_18 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
774+
└─IndexReader_11(Probe) 12.50 root index:IndexRangeScan_10
775+
└─IndexRangeScan_10 12.50 cop[tikv] table:t1, index:idx(b) range: decided by [eq(test.t1.a, test.t.a) eq(test.t1.b, 123)], keep order:false, stats:pseudo
776+
select /*+ inl_join(t1), use_index(t1, idx) */ * from t join t1 on t.a = t1.a and t1.b = 123;
777+
a a b
778+
2 2 123
779+
drop table if exists t1, t2;
780+
create table t1(a int, b int, index idx(a, b));
781+
create table t2(a int, b int, index idx(a));
782+
explain select /*+ merge_join(t1) */ * from t1 join t2 on t1.a=t2.a and t2.b=t1.b;
783+
id estRows task access object operator info
784+
MergeJoin_8 12475.01 root inner join, left key:test.t1.a, test.t1.b, right key:test.t2.a, test.t2.b
785+
├─Sort_23(Build) 9980.01 root test.t2.a, test.t2.b
786+
│ └─TableReader_18 9980.01 root data:Selection_17
787+
│ └─Selection_17 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))
788+
│ └─TableFullScan_16 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
789+
└─IndexReader_11(Probe) 9980.01 root index:Selection_10
790+
└─Selection_10 9980.01 cop[tikv] not(isnull(test.t1.b))
791+
└─IndexFullScan_9 9990.00 cop[tikv] table:t1, index:idx(a, b) keep order:true, stats:pseudo
792+
explain select /*+ no_hash_join(t1), no_index_join(t1,t2), no_index_hash_join(t1,t2) */ * from t1 join t2 on t1.a=t2.a and t2.b=t1.b;
793+
id estRows task access object operator info
794+
MergeJoin_8 12475.01 root inner join, left key:test.t1.a, test.t1.b, right key:test.t2.a, test.t2.b
795+
├─Sort_51(Build) 9980.01 root test.t2.a, test.t2.b
796+
│ └─TableReader_46 9980.01 root data:Selection_45
797+
│ └─Selection_45 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))
798+
│ └─TableFullScan_44 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
799+
└─IndexReader_39(Probe) 9980.01 root index:Selection_38
800+
└─Selection_38 9980.01 cop[tikv] not(isnull(test.t1.b))
801+
└─IndexFullScan_37 9990.00 cop[tikv] table:t1, index:idx(a, b) keep order:true, stats:pseudo
802+
>>>>>>> 163c4bed8fa (planner: don't choose merge join unless there's hint or join key fully matched (#59933))

tests/integrationtest/t/planner/core/issuetest/planner_issue.test

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,74 @@ FROM (
477477
) AS derived_table
478478
WHERE 16739493649928310215 MEMBER OF (derived_table.col_60767)
479479
OR NOT (JSON_CONTAINS(derived_table.col_60767, '6019730272580550835'));
480+
<<<<<<< HEAD
480481
set @@tidb_enable_global_index=0;
482+
=======
483+
484+
# TestIssue53766
485+
drop table if exists t0, t1;
486+
CREATE TABLE t0(c0 int);
487+
CREATE TABLE t1(c0 int);
488+
SELECT t0.c0, t1.c0 FROM t0 NATURAL JOIN t1 WHERE '1' AND (t0.c0 IN (SELECT c0 FROM t0));
489+
490+
# TestIssue56472
491+
drop table if exists t1, t2, t3, t4;
492+
CREATE TABLE t1 (a int, b int, c int);
493+
CREATE TABLE t2 (a int, b int, c int);
494+
CREATE TABLE t3 (a int, b int, c int);
495+
CREATE TABLE t4 (a int, b int, c int);
496+
INSERT INTO t1 VALUES (1,3,0), (2,2,0), (3,2,0);
497+
INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
498+
INSERT INTO t3 VALUES (1,2,0), (2,2,0);
499+
INSERT INTO t4 VALUES (3,2,0), (4,2,0);
500+
CREATE INDEX idx_b ON t2(b);
501+
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
502+
FROM (t3,t4)
503+
LEFT JOIN
504+
(t1,t2)
505+
ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b order by 1, 2, 3, 4, 5;
506+
show warnings;
507+
drop table if exists t1, t2, t3, t4;
508+
509+
# TestIssue56270
510+
drop table if exists t0, v0;
511+
drop view if exists v0;
512+
CREATE TABLE t0(c0 INTEGER);
513+
CREATE VIEW v0(c0) AS SELECT 'a' FROM t0 WHERE (CASE t0.c0 WHEN t0.c0 THEN false END );
514+
SELECT t0.c0 FROM v0, t0 WHERE RAND();
515+
516+
# TestIssue56479
517+
drop table if exists tl6e913fb9;
518+
CREATE TABLE `tl6e913fb9` (
519+
`col_36` varchar(175) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'asMF',
520+
KEY `idx_35_5` (`col_36`(1)),
521+
PRIMARY KEY (`col_36`) /*T![clustered_index] NONCLUSTERED */,
522+
KEY `idx_65` (`col_36`(5))
523+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
524+
with cte_192 ( col_1101,col_1102,col_1103,col_1104 ) AS ( select /*+ use_index_merge( tl6e913fb9 ) */ replace( tl6e913fb9.col_36 , tl6e913fb9.col_36 , tl6e913fb9.col_36 ) as r0 , space( 0 ) as r1 , min( distinct tl6e913fb9.col_36 ) as r2 , count( distinct tl6e913fb9.col_36 ) as r3 from tl6e913fb9 where tl6e913fb9.col_36 between 'n92ok$B%W#UU%O' and '()c=KVQ=T%-vzGJ' and tl6e913fb9.col_36 in ( 'T+kf' ,'Lvluod2H' ,'3#Omx@pC^fFkeH' ,'=b$z' ) group by tl6e913fb9.col_36 having tl6e913fb9.col_36 = 'xjV@' or IsNull( tl6e913fb9.col_36 ) ) ( select 1,col_1101,col_1102,col_1103,col_1104 from cte_192 where not( IsNull( cte_192.col_1102 ) ) order by 1,2,3,4,5 limit 72850972 );
525+
526+
# TestIssue58581
527+
drop table if exists t;
528+
create table t (id int unique key, c int);
529+
insert into t values (1, 10);
530+
insert into t values (2, 20);
531+
insert into t values (3, 30);
532+
select _tidb_rowid from t where id in (1, 2, 3);
533+
534+
# TestIssue59762
535+
drop table if exists t, t1;
536+
create table t(a int);
537+
create table t1(a int primary key, b int, index idx(b));
538+
insert into t values(1), (2), (123);
539+
insert into t1 values(2, 123), (123, 2);
540+
set tidb_opt_fix_control='44855:on';
541+
explain select /*+ inl_join(t1), use_index(t1, idx) */ * from t join t1 on t.a = t1.a and t1.b = 123;
542+
select /*+ inl_join(t1), use_index(t1, idx) */ * from t join t1 on t.a = t1.a and t1.b = 123;
543+
544+
# TestIssue20710
545+
drop table if exists t1, t2;
546+
create table t1(a int, b int, index idx(a, b));
547+
create table t2(a int, b int, index idx(a));
548+
explain select /*+ merge_join(t1) */ * from t1 join t2 on t1.a=t2.a and t2.b=t1.b;
549+
explain select /*+ no_hash_join(t1), no_index_join(t1,t2), no_index_hash_join(t1,t2) */ * from t1 join t2 on t1.a=t2.a and t2.b=t1.b;
550+
>>>>>>> 163c4bed8fa (planner: don't choose merge join unless there's hint or join key fully matched (#59933))

0 commit comments

Comments
 (0)