planner: ban (index) merge join heuristically when convert eq cond to other cond (#21138)

This commit is contained in:
Zhuomin Liu
2020-11-19 17:17:53 +08:00
committed by GitHub
parent 61b9930c5c
commit 38bbb0dd21
10 changed files with 191 additions and 181 deletions

View File

@ -118,28 +118,28 @@ id estRows task access object operator info
Projection_13 1.00 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd.dic, test.dd.ip, test.dd.t, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, test.st.ext, test.st.t
└─Limit_16 1.00 root offset:0, count:2500
└─HashAgg_19 1.00 root group by:test.dd.dic, test.st.aid, funcs:firstrow(test.st.id)->test.st.id, funcs:firstrow(test.st.aid)->test.st.aid, funcs:firstrow(test.st.cm)->test.st.cm, funcs:firstrow(test.st.p1)->test.st.p1, funcs:firstrow(test.st.p2)->test.st.p2, funcs:firstrow(test.st.p3)->test.st.p3, funcs:firstrow(test.st.p4)->test.st.p4, funcs:firstrow(test.st.p5)->test.st.p5, funcs:firstrow(test.st.p6_md5)->test.st.p6_md5, funcs:firstrow(test.st.p7_md5)->test.st.p7_md5, funcs:firstrow(test.st.ext)->test.st.ext, funcs:firstrow(test.st.t)->test.st.t, funcs:firstrow(test.dd.id)->test.dd.id, funcs:firstrow(test.dd.dic)->test.dd.dic, funcs:firstrow(test.dd.ip)->test.dd.ip, funcs:firstrow(test.dd.t)->test.dd.t
└─HashJoin_34 0.00 root inner join, equal:[eq(test.dd.aid, test.st.aid) eq(test.dd.ip, test.st.ip)], other cond:gt(test.dd.t, test.st.t)
├─IndexLookUp_52(Build) 0.00 root
│ ├─IndexRangeScan_49(Build) 3333.33 cop[tikv] table:dd, index:t(t) range:(1478143908,+inf], keep order:false, stats:pseudo
│ └─Selection_51(Probe) 0.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "android"), not(isnull(test.dd.ip))
│ └─TableRowIDScan_50 3333.33 cop[tikv] table:dd keep order:false, stats:pseudo
└─IndexLookUp_41(Probe) 3.33 root
├─IndexRangeScan_38(Build) 3333.33 cop[tikv] table:gad, index:t(t) range:(1478143908,+inf], keep order:false, stats:pseudo
└─Selection_40(Probe) 3.33 cop[tikv] eq(test.st.pt, "android"), not(isnull(test.st.ip))
└─TableRowIDScan_39 3333.33 cop[tikv] table:gad keep order:false, stats:pseudo
└─HashJoin_33 0.00 root inner join, equal:[eq(test.dd.aid, test.st.aid) eq(test.dd.ip, test.st.ip)], other cond:gt(test.dd.t, test.st.t)
├─IndexLookUp_51(Build) 0.00 root
│ ├─IndexRangeScan_48(Build) 3333.33 cop[tikv] table:dd, index:t(t) range:(1478143908,+inf], keep order:false, stats:pseudo
│ └─Selection_50(Probe) 0.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "android"), not(isnull(test.dd.ip))
│ └─TableRowIDScan_49 3333.33 cop[tikv] table:dd keep order:false, stats:pseudo
└─IndexLookUp_40(Probe) 3.33 root
├─IndexRangeScan_37(Build) 3333.33 cop[tikv] table:gad, index:t(t) range:(1478143908,+inf], keep order:false, stats:pseudo
└─Selection_39(Probe) 3.33 cop[tikv] eq(test.st.pt, "android"), not(isnull(test.st.ip))
└─TableRowIDScan_38 3333.33 cop[tikv] table:gad keep order:false, stats:pseudo
explain select gad.id as gid,sdk.id as sid,gad.aid as aid,gad.cm as cm,sdk.dic as dic,sdk.ip as ip, sdk.t as t, gad.p1 as p1, gad.p2 as p2, gad.p3 as p3, gad.p4 as p4, gad.p5 as p5, gad.p6_md5 as p6, gad.p7_md5 as p7, gad.ext as ext from st gad join dd sdk on gad.aid = sdk.aid and gad.dic = sdk.mac and gad.t < sdk.t where gad.t > 1477971479 and gad.bm = 0 and gad.pt = 'ios' and gad.dit = 'mac' and sdk.t > 1477971479 and sdk.bm = 0 and sdk.pt = 'ios' limit 3000;
id estRows task access object operator info
Projection_10 0.00 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd.dic, test.dd.ip, test.dd.t, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, test.st.ext
└─Limit_13 0.00 root offset:0, count:3000
└─IndexMergeJoin_26 0.00 root inner join, inner:IndexLookUp_24, outer key:test.st.aid, inner key:test.dd.aid, other cond:eq(test.st.dic, test.dd.mac), lt(test.st.t, test.dd.t)
├─IndexLookUp_35(Build) 0.00 root
│ ├─IndexRangeScan_32(Build) 3333.33 cop[tikv] table:gad, index:t(t) range:(1477971479,+inf], keep order:false, stats:pseudo
│ └─Selection_34(Probe) 0.00 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), not(isnull(test.st.dic))
│ └─TableRowIDScan_33 3333.33 cop[tikv] table:gad keep order:false, stats:pseudo
└─IndexLookUp_24(Probe) 0.00 root
├─IndexRangeScan_21(Build) 10000.00 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:true, stats:pseudo
└─Selection_23(Probe) 0.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t))
└─TableRowIDScan_22 10000.00 cop[tikv] table:sdk keep order:false, stats:pseudo
└─IndexJoin_18 0.00 root inner join, inner:IndexLookUp_17, outer key:test.st.aid, inner key:test.dd.aid, equal cond:eq(test.st.aid, test.dd.aid), eq(test.st.dic, test.dd.mac), other cond:lt(test.st.t, test.dd.t)
├─IndexLookUp_34(Build) 0.00 root
│ ├─IndexRangeScan_31(Build) 3333.33 cop[tikv] table:gad, index:t(t) range:(1477971479,+inf], keep order:false, stats:pseudo
│ └─Selection_33(Probe) 0.00 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), not(isnull(test.st.dic))
│ └─TableRowIDScan_32 3333.33 cop[tikv] table:gad keep order:false, stats:pseudo
└─IndexLookUp_17(Probe) 0.00 root
├─IndexRangeScan_14(Build) 10000.00 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false, stats:pseudo
└─Selection_16(Probe) 0.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t))
└─TableRowIDScan_15 10000.00 cop[tikv] table:sdk keep order:false, stats:pseudo
explain SELECT cm, p1, p2, p3, p4, p5, p6_md5, p7_md5, count(1) as click_pv, count(DISTINCT ip) as click_ip FROM st WHERE (t between 1478188800 and 1478275200) and aid='cn.sbkcq' and pt='android' GROUP BY cm, p1, p2, p3, p4, p5, p6_md5, p7_md5;
id estRows task access object operator info
Projection_5 1.00 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, Column#20, Column#21

View File

@ -128,25 +128,25 @@ id estRows task access object operator info
Projection_13 424.00 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd.dic, test.dd.ip, test.dd.t, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, test.st.ext, test.st.t
└─Limit_16 424.00 root offset:0, count:2500
└─HashAgg_19 424.00 root group by:test.dd.dic, test.st.aid, funcs:firstrow(test.st.id)->test.st.id, funcs:firstrow(test.st.aid)->test.st.aid, funcs:firstrow(test.st.cm)->test.st.cm, funcs:firstrow(test.st.p1)->test.st.p1, funcs:firstrow(test.st.p2)->test.st.p2, funcs:firstrow(test.st.p3)->test.st.p3, funcs:firstrow(test.st.p4)->test.st.p4, funcs:firstrow(test.st.p5)->test.st.p5, funcs:firstrow(test.st.p6_md5)->test.st.p6_md5, funcs:firstrow(test.st.p7_md5)->test.st.p7_md5, funcs:firstrow(test.st.ext)->test.st.ext, funcs:firstrow(test.st.t)->test.st.t, funcs:firstrow(test.dd.id)->test.dd.id, funcs:firstrow(test.dd.dic)->test.dd.dic, funcs:firstrow(test.dd.ip)->test.dd.ip, funcs:firstrow(test.dd.t)->test.dd.t
└─HashJoin_34 424.00 root inner join, equal:[eq(test.st.aid, test.dd.aid) eq(test.st.ip, test.dd.ip)], other cond:gt(test.dd.t, test.st.t)
├─TableReader_37(Build) 424.00 root data:Selection_36
│ └─Selection_36 424.00 cop[tikv] eq(test.st.bm, 0), eq(test.st.pt, "android"), gt(test.st.t, 1478143908), not(isnull(test.st.ip))
│ └─TableRangeScan_35 1999.00 cop[tikv] table:gad range:[0,+inf], keep order:false
└─TableReader_44(Probe) 455.80 root data:Selection_43
└─Selection_43 455.80 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908), not(isnull(test.dd.ip)), not(isnull(test.dd.t))
└─TableRangeScan_42 2000.00 cop[tikv] table:dd range:[0,+inf], keep order:false
└─HashJoin_33 424.00 root inner join, equal:[eq(test.st.aid, test.dd.aid) eq(test.st.ip, test.dd.ip)], other cond:gt(test.dd.t, test.st.t)
├─TableReader_36(Build) 424.00 root data:Selection_35
│ └─Selection_35 424.00 cop[tikv] eq(test.st.bm, 0), eq(test.st.pt, "android"), gt(test.st.t, 1478143908), not(isnull(test.st.ip))
│ └─TableRangeScan_34 1999.00 cop[tikv] table:gad range:[0,+inf], keep order:false
└─TableReader_43(Probe) 455.80 root data:Selection_42
└─Selection_42 455.80 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908), not(isnull(test.dd.ip)), not(isnull(test.dd.t))
└─TableRangeScan_41 2000.00 cop[tikv] table:dd range:[0,+inf], keep order:false
explain select gad.id as gid,sdk.id as sid,gad.aid as aid,gad.cm as cm,sdk.dic as dic,sdk.ip as ip, sdk.t as t, gad.p1 as p1, gad.p2 as p2, gad.p3 as p3, gad.p4 as p4, gad.p5 as p5, gad.p6_md5 as p6, gad.p7_md5 as p7, gad.ext as ext from st gad join dd sdk on gad.aid = sdk.aid and gad.dic = sdk.mac and gad.t < sdk.t where gad.t > 1477971479 and gad.bm = 0 and gad.pt = 'ios' and gad.dit = 'mac' and sdk.t > 1477971479 and sdk.bm = 0 and sdk.pt = 'ios' limit 3000;
id estRows task access object operator info
Projection_10 170.34 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd.dic, test.dd.ip, test.dd.t, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, test.st.ext
└─Limit_13 170.34 root offset:0, count:3000
└─IndexMergeJoin_26 170.34 root inner join, inner:IndexLookUp_24, outer key:test.st.aid, inner key:test.dd.aid, other cond:eq(test.st.dic, test.dd.mac), lt(test.st.t, test.dd.t)
├─TableReader_31(Build) 170.34 root data:Selection_30
│ └─Selection_30 170.34 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), gt(test.st.t, 1477971479), not(isnull(test.st.dic))
│ └─TableRangeScan_29 1999.00 cop[tikv] table:gad range:[0,+inf], keep order:false
└─IndexLookUp_24(Probe) 1.00 root
├─IndexRangeScan_21(Build) 3.93 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:true
└─Selection_23(Probe) 1.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t))
└─TableRowIDScan_22 3.93 cop[tikv] table:sdk keep order:false
└─IndexJoin_18 170.34 root inner join, inner:IndexLookUp_17, outer key:test.st.aid, inner key:test.dd.aid, equal cond:eq(test.st.aid, test.dd.aid), eq(test.st.dic, test.dd.mac), other cond:lt(test.st.t, test.dd.t)
├─TableReader_30(Build) 170.34 root data:Selection_29
│ └─Selection_29 170.34 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), gt(test.st.t, 1477971479), not(isnull(test.st.dic))
│ └─TableRangeScan_28 1999.00 cop[tikv] table:gad range:[0,+inf], keep order:false
└─IndexLookUp_17(Probe) 1.00 root
├─IndexRangeScan_14(Build) 3.93 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false
└─Selection_16(Probe) 1.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t))
└─TableRowIDScan_15 3.93 cop[tikv] table:sdk keep order:false
explain SELECT cm, p1, p2, p3, p4, p5, p6_md5, p7_md5, count(1) as click_pv, count(DISTINCT ip) as click_ip FROM st WHERE (t between 1478188800 and 1478275200) and aid='cn.sbkcq' and pt='android' GROUP BY cm, p1, p2, p3, p4, p5, p6_md5, p7_md5;
id estRows task access object operator info
Projection_5 39.28 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, Column#20, Column#21

View File

@ -184,37 +184,37 @@ limit 100;
id estRows task access object operator info
Projection_37 100.00 root tpch.supplier.s_acctbal, tpch.supplier.s_name, tpch.nation.n_name, tpch.part.p_partkey, tpch.part.p_mfgr, tpch.supplier.s_address, tpch.supplier.s_phone, tpch.supplier.s_comment
└─TopN_40 100.00 root tpch.supplier.s_acctbal:desc, tpch.nation.n_name, tpch.supplier.s_name, tpch.part.p_partkey, offset:0, count:100
└─HashJoin_46 155496.00 root inner join, equal:[eq(tpch.part.p_partkey, tpch.partsupp.ps_partkey) eq(tpch.partsupp.ps_supplycost, Column#50)]
├─HashJoin_60(Build) 155496.00 root inner join, equal:[eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)]
│ ├─TableReader_90(Build) 155496.00 root data:Selection_89
│ │ └─Selection_89 155496.00 cop[tikv] eq(tpch.part.p_size, 30), like(tpch.part.p_type, "%STEEL", 92)
│ │ └─TableFullScan_88 10000000.00 cop[tikv] table:part keep order:false
│ └─HashJoin_63(Probe) 8155010.44 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)]
│ ├─HashJoin_65(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ │ ├─HashJoin_78(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ │ ├─TableReader_83(Build) 1.00 root data:Selection_82
│ │ │ │ └─Selection_82 1.00 cop[tikv] eq(tpch.region.r_name, "ASIA")
│ │ │ │ └─TableFullScan_81 5.00 cop[tikv] table:region keep order:false
│ │ │ └─TableReader_80(Probe) 25.00 root data:TableFullScan_79
│ │ │ └─TableFullScan_79 25.00 cop[tikv] table:nation keep order:false
│ │ └─TableReader_85(Probe) 500000.00 root data:TableFullScan_84
│ │ └─TableFullScan_84 500000.00 cop[tikv] table:supplier keep order:false
│ └─TableReader_87(Probe) 40000000.00 root data:TableFullScan_86
│ └─TableFullScan_86 40000000.00 cop[tikv] table:partsupp keep order:false
└─Selection_91(Probe) 6524008.35 root not(isnull(Column#50))
└─HashAgg_94 8155010.44 root group by:tpch.partsupp.ps_partkey, funcs:min(tpch.partsupp.ps_supplycost)->Column#50, funcs:firstrow(tpch.partsupp.ps_partkey)->tpch.partsupp.ps_partkey
└─HashJoin_98 8155010.44 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)]
├─HashJoin_100(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ ├─HashJoin_113(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ ├─TableReader_118(Build) 1.00 root data:Selection_117
│ │ │ └─Selection_117 1.00 cop[tikv] eq(tpch.region.r_name, "ASIA")
│ │ │ └─TableFullScan_116 5.00 cop[tikv] table:region keep order:false
│ │ └─TableReader_115(Probe) 25.00 root data:TableFullScan_114
│ │ └─TableFullScan_114 25.00 cop[tikv] table:nation keep order:false
│ └─TableReader_120(Probe) 500000.00 root data:TableFullScan_119
│ └─TableFullScan_119 500000.00 cop[tikv] table:supplier keep order:false
└─TableReader_122(Probe) 40000000.00 root data:TableFullScan_121
└─TableFullScan_121 40000000.00 cop[tikv] table:partsupp keep order:false
└─HashJoin_45 155496.00 root inner join, equal:[eq(tpch.part.p_partkey, tpch.partsupp.ps_partkey) eq(tpch.partsupp.ps_supplycost, Column#50)]
├─HashJoin_58(Build) 155496.00 root inner join, equal:[eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)]
│ ├─TableReader_88(Build) 155496.00 root data:Selection_87
│ │ └─Selection_87 155496.00 cop[tikv] eq(tpch.part.p_size, 30), like(tpch.part.p_type, "%STEEL", 92)
│ │ └─TableFullScan_86 10000000.00 cop[tikv] table:part keep order:false
│ └─HashJoin_61(Probe) 8155010.44 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)]
│ ├─HashJoin_63(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ │ ├─HashJoin_76(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ │ ├─TableReader_81(Build) 1.00 root data:Selection_80
│ │ │ │ └─Selection_80 1.00 cop[tikv] eq(tpch.region.r_name, "ASIA")
│ │ │ │ └─TableFullScan_79 5.00 cop[tikv] table:region keep order:false
│ │ │ └─TableReader_78(Probe) 25.00 root data:TableFullScan_77
│ │ │ └─TableFullScan_77 25.00 cop[tikv] table:nation keep order:false
│ │ └─TableReader_83(Probe) 500000.00 root data:TableFullScan_82
│ │ └─TableFullScan_82 500000.00 cop[tikv] table:supplier keep order:false
│ └─TableReader_85(Probe) 40000000.00 root data:TableFullScan_84
│ └─TableFullScan_84 40000000.00 cop[tikv] table:partsupp keep order:false
└─Selection_89(Probe) 6524008.35 root not(isnull(Column#50))
└─HashAgg_92 8155010.44 root group by:tpch.partsupp.ps_partkey, funcs:min(tpch.partsupp.ps_supplycost)->Column#50, funcs:firstrow(tpch.partsupp.ps_partkey)->tpch.partsupp.ps_partkey
└─HashJoin_96 8155010.44 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)]
├─HashJoin_98(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ ├─HashJoin_111(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ ├─TableReader_116(Build) 1.00 root data:Selection_115
│ │ │ └─Selection_115 1.00 cop[tikv] eq(tpch.region.r_name, "ASIA")
│ │ │ └─TableFullScan_114 5.00 cop[tikv] table:region keep order:false
│ │ └─TableReader_113(Probe) 25.00 root data:TableFullScan_112
│ │ └─TableFullScan_112 25.00 cop[tikv] table:nation keep order:false
│ └─TableReader_118(Probe) 500000.00 root data:TableFullScan_117
│ └─TableFullScan_117 500000.00 cop[tikv] table:supplier keep order:false
└─TableReader_120(Probe) 40000000.00 root data:TableFullScan_119
└─TableFullScan_119 40000000.00 cop[tikv] table:partsupp keep order:false
/*
Q3 Shipping Priority Query
This query retrieves the 10 unshipped orders with the highest value.
@ -345,26 +345,26 @@ id estRows task access object operator info
Sort_23 5.00 root Column#49:desc
└─Projection_25 5.00 root tpch.nation.n_name, Column#49
└─HashAgg_28 5.00 root group by:Column#52, funcs:sum(Column#50)->Column#49, funcs:firstrow(Column#51)->tpch.nation.n_name
└─Projection_86 11822812.50 root mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#50, tpch.nation.n_name, tpch.nation.n_name
└─HashJoin_38 11822812.50 root inner join, equal:[eq(tpch.supplier.s_nationkey, tpch.customer.c_nationkey) eq(tpch.orders.o_custkey, tpch.customer.c_custkey)]
├─TableReader_84(Build) 7500000.00 root data:TableFullScan_83
│ └─TableFullScan_83 7500000.00 cop[tikv] table:customer keep order:false
└─HashJoin_52(Probe) 11822812.50 root inner join, equal:[eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)]
├─TableReader_82(Build) 11822812.50 root data:Selection_81
│ └─Selection_81 11822812.50 cop[tikv] ge(tpch.orders.o_orderdate, 1994-01-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1995-01-01)
│ └─TableFullScan_80 75000000.00 cop[tikv] table:orders keep order:false
└─HashJoin_55(Probe) 61163763.01 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)]
├─HashJoin_57(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ ├─HashJoin_70(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ ├─TableReader_75(Build) 1.00 root data:Selection_74
│ │ │ └─Selection_74 1.00 cop[tikv] eq(tpch.region.r_name, "MIDDLE EAST")
│ │ │ └─TableFullScan_73 5.00 cop[tikv] table:region keep order:false
│ │ └─TableReader_72(Probe) 25.00 root data:TableFullScan_71
│ │ └─TableFullScan_71 25.00 cop[tikv] table:nation keep order:false
│ └─TableReader_77(Probe) 500000.00 root data:TableFullScan_76
│ └─TableFullScan_76 500000.00 cop[tikv] table:supplier keep order:false
└─TableReader_79(Probe) 300005811.00 root data:TableFullScan_78
└─TableFullScan_78 300005811.00 cop[tikv] table:lineitem keep order:false
└─Projection_85 11822812.50 root mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#50, tpch.nation.n_name, tpch.nation.n_name
└─HashJoin_37 11822812.50 root inner join, equal:[eq(tpch.supplier.s_nationkey, tpch.customer.c_nationkey) eq(tpch.orders.o_custkey, tpch.customer.c_custkey)]
├─TableReader_83(Build) 7500000.00 root data:TableFullScan_82
│ └─TableFullScan_82 7500000.00 cop[tikv] table:customer keep order:false
└─HashJoin_51(Probe) 11822812.50 root inner join, equal:[eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)]
├─TableReader_81(Build) 11822812.50 root data:Selection_80
│ └─Selection_80 11822812.50 cop[tikv] ge(tpch.orders.o_orderdate, 1994-01-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1995-01-01)
│ └─TableFullScan_79 75000000.00 cop[tikv] table:orders keep order:false
└─HashJoin_54(Probe) 61163763.01 root inner join, equal:[eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)]
├─HashJoin_56(Build) 100000.00 root inner join, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)]
│ ├─HashJoin_69(Build) 5.00 root inner join, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)]
│ │ ├─TableReader_74(Build) 1.00 root data:Selection_73
│ │ │ └─Selection_73 1.00 cop[tikv] eq(tpch.region.r_name, "MIDDLE EAST")
│ │ │ └─TableFullScan_72 5.00 cop[tikv] table:region keep order:false
│ │ └─TableReader_71(Probe) 25.00 root data:TableFullScan_70
│ │ └─TableFullScan_70 25.00 cop[tikv] table:nation keep order:false
│ └─TableReader_76(Probe) 500000.00 root data:TableFullScan_75
│ └─TableFullScan_75 500000.00 cop[tikv] table:supplier keep order:false
└─TableReader_78(Probe) 300005811.00 root data:TableFullScan_77
└─TableFullScan_77 300005811.00 cop[tikv] table:lineitem keep order:false
/*
Q6 Forecasting Revenue Change Query
This query quantifies the amount of revenue increase that would have resulted from eliminating certain companywide

View File

@ -140,17 +140,15 @@
}
],
"Plan": [
"MergeJoin_9 6387.21 root inner join, left key:test.t1.a, right key:test.t2.a, other cond:eq(test.t1.b, test.t2.b)",
"├─Projection_59(Build) 99.80 root test.t2.a, test.t2.b, test.t2.c",
"│ └─IndexLookUp_58 99.80 root ",
"│ ├─Selection_57(Build) 99.80 cop[tikv] not(isnull(test.t2.b))",
"│ │ └─IndexRangeScan_55 99.90 cop[tikv] table:t2, index:b(b, a) range:[1 -inf,1 +inf], keep order:true, stats:pseudo",
"│ └─TableRowIDScan_56(Probe) 99.80 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─Projection_54(Probe) 99.80 root test.t1.a, test.t1.b, test.t1.c",
" └─IndexLookUp_53 99.80 root ",
" ├─Selection_52(Build) 99.80 cop[tikv] not(isnull(test.t1.b))",
" │ └─IndexRangeScan_50 99.90 cop[tikv] table:t1, index:b(b, a) range:[1 -inf,1 +inf], keep order:true, stats:pseudo",
" └─TableRowIDScan_51(Probe) 99.80 cop[tikv] table:t1 keep order:false, stats:pseudo"
"HashJoin_37 6387.21 root inner join, equal:[eq(test.t1.b, test.t2.b) eq(test.t1.a, test.t2.a)]",
"├─IndexLookUp_62(Build) 99.80 root ",
"│ ├─Selection_61(Build) 99.80 cop[tikv] not(isnull(test.t2.b))",
"│ │ └─IndexRangeScan_59 99.90 cop[tikv] table:t2, index:b(b, a) range:[1 -inf,1 +inf], keep order:false, stats:pseudo",
"│ └─TableRowIDScan_60(Probe) 99.80 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─IndexLookUp_55(Probe) 99.80 root ",
" ├─Selection_54(Build) 99.80 cop[tikv] not(isnull(test.t1.b))",
" └─IndexRangeScan_52 99.90 cop[tikv] table:t1, index:b(b, a) range:[1 -inf,1 +inf], keep order:false, stats:pseudo",
" └─TableRowIDScan_53(Probe) 99.80 cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"LastPlanUseCache": "0",
"Result": null
@ -164,17 +162,15 @@
}
],
"Plan": [
"MergeJoin_9 6387.21 root inner join, left key:test.t1.a, right key:test.t2.a, other cond:eq(test.t1.b, test.t2.b)",
"├─Projection_59(Build) 99.80 root test.t2.a, test.t2.b, test.t2.c",
"│ └─IndexLookUp_58 99.80 root ",
"│ ├─Selection_57(Build) 99.80 cop[tikv] not(isnull(test.t2.b))",
"│ │ └─IndexRangeScan_55 99.90 cop[tikv] table:t2, index:b(b, a) range:[2 -inf,2 +inf], keep order:true, stats:pseudo",
"│ └─TableRowIDScan_56(Probe) 99.80 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─Projection_54(Probe) 99.80 root test.t1.a, test.t1.b, test.t1.c",
" └─IndexLookUp_53 99.80 root ",
" ├─Selection_52(Build) 99.80 cop[tikv] not(isnull(test.t1.b))",
" │ └─IndexRangeScan_50 99.90 cop[tikv] table:t1, index:b(b, a) range:[2 -inf,2 +inf], keep order:true, stats:pseudo",
" └─TableRowIDScan_51(Probe) 99.80 cop[tikv] table:t1 keep order:false, stats:pseudo"
"HashJoin_37 6387.21 root inner join, equal:[eq(test.t1.b, test.t2.b) eq(test.t1.a, test.t2.a)]",
"├─IndexLookUp_62(Build) 99.80 root ",
"│ ├─Selection_61(Build) 99.80 cop[tikv] not(isnull(test.t2.b))",
"│ │ └─IndexRangeScan_59 99.90 cop[tikv] table:t2, index:b(b, a) range:[2 -inf,2 +inf], keep order:false, stats:pseudo",
"│ └─TableRowIDScan_60(Probe) 99.80 cop[tikv] table:t2 keep order:false, stats:pseudo",
"└─IndexLookUp_55(Probe) 99.80 root ",
" ├─Selection_54(Build) 99.80 cop[tikv] not(isnull(test.t1.b))",
" └─IndexRangeScan_52 99.90 cop[tikv] table:t1, index:b(b, a) range:[2 -inf,2 +inf], keep order:false, stats:pseudo",
" └─TableRowIDScan_53(Probe) 99.80 cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"LastPlanUseCache": "1",
"Result": [

View File

@ -153,7 +153,9 @@ func (p *LogicalJoin) GetMergeJoin(prop *property.PhysicalProperty, schema *expr
}
for _, lhsChildProperty := range p.leftProperties {
offsets := getMaxSortPrefix(lhsChildProperty, leftJoinKeys)
if len(offsets) == 0 {
// If not all equal conditions hit properties. We ban merge join heuristically. Because in this case, merge join
// may get a very low performance. In executor, executes join results before other conditions filter it.
if len(offsets) < len(leftJoinKeys) {
continue
}
@ -391,7 +393,6 @@ func (p *LogicalJoin) getHashJoin(prop *property.PhysicalProperty, innerIdx int,
// When inner plan is TableReader, the parameter `ranges` will be nil. Because pk only have one column. So all of its range
// is generated during execution time.
func (p *LogicalJoin) constructIndexJoin(
joinTP string,
prop *property.PhysicalProperty,
outerIdx int,
innerTask task,
@ -440,36 +441,33 @@ func (p *LogicalJoin) constructIndexJoin(
}
var outerHashKeys, innerHashKeys []*expression.Column
// HashKey is only used for IndexJoin and IndexHashJoin since they need to
// build hash tables.
if joinTP != plancodec.TypeIndexMergeJoin {
outerHashKeys, innerHashKeys = make([]*expression.Column, len(newOuterKeys)), make([]*expression.Column, len(newInnerKeys))
copy(outerHashKeys, newOuterKeys)
copy(innerHashKeys, newInnerKeys)
// we can use the `col <eq> col` in `OtherCondition` to build the hashtable to avoid the unnecessary calculating.
for i := len(newOtherConds) - 1; i >= 0; i = i - 1 {
switch c := newOtherConds[i].(type) {
case *expression.ScalarFunction:
if c.FuncName.L == ast.EQ {
lhs, ok1 := c.GetArgs()[0].(*expression.Column)
rhs, ok2 := c.GetArgs()[1].(*expression.Column)
if ok1 && ok2 {
outerSchema, innerSchema := p.Children()[outerIdx].Schema(), p.Children()[1-outerIdx].Schema()
if outerSchema.Contains(lhs) && innerSchema.Contains(rhs) {
outerHashKeys = append(outerHashKeys, lhs)
innerHashKeys = append(innerHashKeys, rhs)
} else if innerSchema.Contains(lhs) && outerSchema.Contains(rhs) {
outerHashKeys = append(outerHashKeys, rhs)
innerHashKeys = append(innerHashKeys, lhs)
}
newOtherConds = append(newOtherConds[:i], newOtherConds[i+1:]...)
outerHashKeys, innerHashKeys = make([]*expression.Column, len(newOuterKeys)), make([]*expression.Column, len(newInnerKeys))
copy(outerHashKeys, newOuterKeys)
copy(innerHashKeys, newInnerKeys)
// we can use the `col <eq> col` in `OtherCondition` to build the hashtable to avoid the unnecessary calculating.
for i := len(newOtherConds) - 1; i >= 0; i = i - 1 {
switch c := newOtherConds[i].(type) {
case *expression.ScalarFunction:
if c.FuncName.L == ast.EQ {
lhs, ok1 := c.GetArgs()[0].(*expression.Column)
rhs, ok2 := c.GetArgs()[1].(*expression.Column)
if ok1 && ok2 {
outerSchema, innerSchema := p.Children()[outerIdx].Schema(), p.Children()[1-outerIdx].Schema()
if outerSchema.Contains(lhs) && innerSchema.Contains(rhs) {
outerHashKeys = append(outerHashKeys, lhs)
innerHashKeys = append(innerHashKeys, rhs)
} else if innerSchema.Contains(lhs) && outerSchema.Contains(rhs) {
outerHashKeys = append(outerHashKeys, rhs)
innerHashKeys = append(innerHashKeys, lhs)
}
newOtherConds = append(newOtherConds[:i], newOtherConds[i+1:]...)
}
default:
continue
}
default:
continue
}
}
baseJoin := basePhysicalJoin{
InnerChildIdx: 1 - outerIdx,
LeftConditions: p.LeftConditions,
@ -506,10 +504,14 @@ func (p *LogicalJoin) constructIndexMergeJoin(
path *util.AccessPath,
compareFilters *ColWithCmpFuncManager,
) []PhysicalPlan {
indexJoins := p.constructIndexJoin(plancodec.TypeIndexMergeJoin, prop, outerIdx, innerTask, ranges, keyOff2IdxOff, path, compareFilters)
indexJoins := p.constructIndexJoin(prop, outerIdx, innerTask, ranges, keyOff2IdxOff, path, compareFilters)
indexMergeJoins := make([]PhysicalPlan, 0, len(indexJoins))
for _, plan := range indexJoins {
join := plan.(*PhysicalIndexJoin)
// Index merge join can't handle hash keys. So we ban it heuristically.
if len(join.InnerHashKeys) > len(join.InnerJoinKeys) {
return nil
}
hasPrefixCol := false
for _, l := range join.IdxColLens {
if l != types.UnspecifiedLength {
@ -591,7 +593,7 @@ func (p *LogicalJoin) constructIndexHashJoin(
path *util.AccessPath,
compareFilters *ColWithCmpFuncManager,
) []PhysicalPlan {
indexJoins := p.constructIndexJoin(plancodec.TypeIndexHashJoin, prop, outerIdx, innerTask, ranges, keyOff2IdxOff, path, compareFilters)
indexJoins := p.constructIndexJoin(prop, outerIdx, innerTask, ranges, keyOff2IdxOff, path, compareFilters)
indexHashJoins := make([]PhysicalPlan, 0, len(indexJoins))
for _, plan := range indexJoins {
join := plan.(*PhysicalIndexJoin)
@ -759,7 +761,7 @@ func (p *LogicalJoin) buildIndexJoinInner2TableScan(
failpoint.Return(p.constructIndexHashJoin(prop, outerIdx, innerTask, nil, keyOff2IdxOff, nil, nil))
}
})
joins = append(joins, p.constructIndexJoin(plancodec.TypeIndexJoin, prop, outerIdx, innerTask, ranges, keyOff2IdxOff, nil, nil)...)
joins = append(joins, p.constructIndexJoin(prop, outerIdx, innerTask, ranges, keyOff2IdxOff, nil, nil)...)
// We can reuse the `innerTask` here since index nested loop hash join
// do not need the inner child to promise the order.
joins = append(joins, p.constructIndexHashJoin(prop, outerIdx, innerTask, ranges, keyOff2IdxOff, nil, nil)...)
@ -794,7 +796,7 @@ func (p *LogicalJoin) buildIndexJoinInner2IndexScan(
failpoint.Return(p.constructIndexHashJoin(prop, outerIdx, innerTask, helper.chosenRanges, keyOff2IdxOff, helper.chosenPath, helper.lastColManager))
}
})
joins = append(joins, p.constructIndexJoin(plancodec.TypeIndexJoin, prop, outerIdx, innerTask, helper.chosenRanges, keyOff2IdxOff, helper.chosenPath, helper.lastColManager)...)
joins = append(joins, p.constructIndexJoin(prop, outerIdx, innerTask, helper.chosenRanges, keyOff2IdxOff, helper.chosenPath, helper.lastColManager)...)
// We can reuse the `innerTask` here since index nested loop hash join
// do not need the inner child to promise the order.
joins = append(joins, p.constructIndexHashJoin(prop, outerIdx, innerTask, helper.chosenRanges, keyOff2IdxOff, helper.chosenPath, helper.lastColManager)...)

View File

@ -489,10 +489,15 @@ func (p *basePhysicalAgg) ExplainNormalizedInfo() string {
// ExplainInfo implements Plan interface.
func (p *PhysicalIndexJoin) ExplainInfo() string {
return p.explainInfo(false)
return p.explainInfo(false, false)
}
func (p *PhysicalIndexJoin) explainInfo(normalized bool) string {
// ExplainInfo implements Plan interface.
func (p *PhysicalIndexMergeJoin) ExplainInfo() string {
return p.explainInfo(false, true)
}
func (p *PhysicalIndexJoin) explainInfo(normalized bool, isIndexMergeJoin bool) string {
sortedExplainExpressionList := expression.SortedExplainExpressionList
if normalized {
sortedExplainExpressionList = expression.SortedExplainNormalizedExpressionList
@ -513,7 +518,7 @@ func (p *PhysicalIndexJoin) explainInfo(normalized bool) string {
expression.ExplainColumnList(p.InnerJoinKeys))
}
if len(p.OuterHashKeys) > 0 {
if len(p.OuterHashKeys) > 0 && !isIndexMergeJoin {
exprs := make([]expression.Expression, 0, len(p.OuterHashKeys))
for i := range p.OuterHashKeys {
expr, err := expression.NewFunctionBase(MockContext(), ast.EQ, types.NewFieldType(mysql.TypeLonglong), p.OuterHashKeys[i], p.InnerHashKeys[i])
@ -541,7 +546,12 @@ func (p *PhysicalIndexJoin) explainInfo(normalized bool) string {
// ExplainNormalizedInfo implements Plan interface.
func (p *PhysicalIndexJoin) ExplainNormalizedInfo() string {
return p.explainInfo(true)
return p.explainInfo(true, false)
}
// ExplainNormalizedInfo implements Plan interface.
func (p *PhysicalIndexMergeJoin) ExplainNormalizedInfo() string {
return p.explainInfo(true, true)
}
// ExplainInfo implements Plan interface.

View File

@ -143,9 +143,9 @@
],
"Plan": [
"IndexJoin_9 12475.01 root inner join, inner:IndexReader_8, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.c, test.t2.c), other cond:gt(test.t2.b, minus(test.t1.b, 1)), lt(test.t2.b, plus(test.t1.b, 1))",
"├─TableReader_19(Build) 9980.01 root data:Selection_18",
"│ └─Selection_18 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.c))",
"│ └─TableFullScan_17 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
"├─TableReader_18(Build) 9980.01 root data:Selection_17",
"│ └─Selection_17 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.c))",
"│ └─TableFullScan_16 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
"└─IndexReader_8(Probe) 1.25 root index:Selection_7",
" └─Selection_7 1.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.c))",
" └─IndexRangeScan_6 1.25 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) gt(test.t2.b, minus(test.t1.b, 1)) lt(test.t2.b, plus(test.t1.b, 1))], keep order:false, stats:pseudo"

View File

@ -514,9 +514,9 @@
"SQL": "explain select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.b",
"Plan": [
"IndexJoin_11 12475.01 root inner join, inner:IndexLookUp_10, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)",
"├─TableReader_24(Build) 9980.01 root data:Selection_23",
"│ └─Selection_23 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_22 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_23(Build) 9980.01 root data:Selection_22",
"│ └─Selection_22 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_21 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_10(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
@ -528,9 +528,9 @@
"SQL": "explain select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.a",
"Plan": [
"IndexJoin_10 12475.01 root inner join, inner:IndexLookUp_9, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)",
"├─TableReader_22(Build) 9980.01 root data:Selection_21",
"│ └─Selection_21 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_20 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_21(Build) 9980.01 root data:Selection_20",
"│ └─Selection_20 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_19 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_9(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
@ -541,9 +541,9 @@
"SQL": "explain select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.a = s.b",
"Plan": [
"IndexJoin_11 12475.01 root inner join, inner:IndexLookUp_10, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)",
"├─TableReader_24(Build) 9990.00 root data:Selection_23",
"│ └─Selection_23 9990.00 cop[tikv] not(isnull(test.t.a))",
"│ └─TableFullScan_22 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_23(Build) 9990.00 root data:Selection_22",
"│ └─Selection_22 9990.00 cop[tikv] not(isnull(test.t.a))",
"│ └─TableFullScan_21 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_10(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
@ -555,9 +555,9 @@
"SQL": "explain select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.b",
"Plan": [
"IndexHashJoin_13 12475.01 root inner join, inner:IndexLookUp_10, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)",
"├─TableReader_24(Build) 9980.01 root data:Selection_23",
"│ └─Selection_23 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_22 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_23(Build) 9980.01 root data:Selection_22",
"│ └─Selection_22 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_21 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_10(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
@ -569,9 +569,9 @@
"SQL": "explain select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.a",
"Plan": [
"IndexHashJoin_12 12475.01 root inner join, inner:IndexLookUp_9, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)",
"├─TableReader_22(Build) 9980.01 root data:Selection_21",
"│ └─Selection_21 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_20 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_21(Build) 9980.01 root data:Selection_20",
"│ └─Selection_20 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
"│ └─TableFullScan_19 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_9(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
@ -582,9 +582,9 @@
"SQL": "explain select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.a = s.b",
"Plan": [
"IndexHashJoin_13 12475.01 root inner join, inner:IndexLookUp_10, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)",
"├─TableReader_24(Build) 9990.00 root data:Selection_23",
"│ └─Selection_23 9990.00 cop[tikv] not(isnull(test.t.a))",
"│ └─TableFullScan_22 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"├─TableReader_23(Build) 9990.00 root data:Selection_22",
"│ └─Selection_22 9990.00 cop[tikv] not(isnull(test.t.a))",
"│ └─TableFullScan_21 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
"└─IndexLookUp_10(Probe) 1.25 root ",
" ├─Selection_8(Build) 1.25 cop[tikv] not(isnull(test.s.a))",
" │ └─IndexRangeScan_6 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",

View File

@ -69,8 +69,8 @@
"SQL": "explain select /*+ inl_join(t2) */ * from t1, t2 where t1.a = t2.a and t1.b = t2.b and t1.c = t2.c",
"Plan": [
"IndexJoin_10 3.00 root inner join, inner:IndexLookUp_9, outer key:test.t1.c, inner key:test.t2.c, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b), eq(test.t1.c, test.t2.c)",
"├─TableReader_20(Build) 3.00 root data:TableFullScan_19",
"│ └─TableFullScan_19 3.00 cop[tikv] table:t1 keep order:false",
"├─TableReader_19(Build) 3.00 root data:TableFullScan_18",
"│ └─TableFullScan_18 3.00 cop[tikv] table:t1 keep order:false",
"└─IndexLookUp_9(Probe) 1.00 root ",
" ├─IndexRangeScan_7(Build) 1.00 cop[tikv] table:t2, index:idx2(c) range: decided by [eq(test.t2.c, test.t1.c)], keep order:false",
" └─TableRowIDScan_8(Probe) 1.00 cop[tikv] table:t2 keep order:false"
@ -175,8 +175,8 @@
"SQL": "explain select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a = t2.a and t1.c = t2.c",
"Plan": [
"IndexJoin_9 2.00 root inner join, inner:IndexLookUp_8, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.c, test.t2.c)",
"├─TableReader_19(Build) 1.00 root data:TableFullScan_18",
"│ └─TableFullScan_18 1.00 cop[tikv] table:t1 keep order:false",
"├─TableReader_18(Build) 1.00 root data:TableFullScan_17",
"│ └─TableFullScan_17 1.00 cop[tikv] table:t1 keep order:false",
"└─IndexLookUp_8(Probe) 2.00 root ",
" ├─IndexRangeScan_6(Build) 2.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false",
" └─TableRowIDScan_7(Probe) 2.00 cop[tikv] table:t2 keep order:false"
@ -348,23 +348,23 @@
{
"SQL": "desc select /*+ TIDB_INLJ(t2)*/ * from t1, t2 where t1.a = t2.a and t1.b = t2.b",
"Plan": [
"IndexJoin_15 12487.50 root inner join, inner:TableReader_11, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)",
"├─IndexReader_21(Build) 9990.00 root index:IndexFullScan_20",
"│ └─IndexFullScan_20 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
"└─TableReader_11(Probe) 1.00 root data:Selection_10",
" └─Selection_10 1.00 cop[tikv] not(isnull(test.t2.b))",
" └─TableRangeScan_9 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo"
"IndexJoin_14 12487.50 root inner join, inner:TableReader_10, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)",
"├─IndexReader_19(Build) 9990.00 root index:IndexFullScan_18",
"│ └─IndexFullScan_18 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
"└─TableReader_10(Probe) 1.00 root data:Selection_9",
" └─Selection_9 1.00 cop[tikv] not(isnull(test.t2.b))",
" └─TableRangeScan_8 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo"
]
},
{
"SQL": "desc select /*+ TIDB_INLJ(t2)*/ * from t1, t2 where t1.a = t2.a and t1.b = t2.a and t1.b = t2.b",
"Plan": [
"IndexJoin_15 12487.50 root inner join, inner:TableReader_11, outer key:test.t1.a, test.t1.b, inner key:test.t2.a, test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.a), eq(test.t1.b, test.t2.b)",
"├─IndexReader_20(Build) 9990.00 root index:IndexFullScan_19",
"│ └─IndexFullScan_19 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
"└─TableReader_11(Probe) 1.00 root data:Selection_10",
" └─Selection_10 1.00 cop[tikv] not(isnull(test.t2.b))",
" └─TableRangeScan_9 1.00 cop[tikv] table:t2 range: decided by [test.t1.a test.t1.b], keep order:false, stats:pseudo"
"IndexJoin_13 12487.50 root inner join, inner:TableReader_9, outer key:test.t1.a, test.t1.b, inner key:test.t2.a, test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.a), eq(test.t1.b, test.t2.b)",
"├─IndexReader_18(Build) 9990.00 root index:IndexFullScan_17",
"│ └─IndexFullScan_17 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
"└─TableReader_9(Probe) 1.00 root data:Selection_8",
" └─Selection_8 1.00 cop[tikv] not(isnull(test.t2.b))",
" └─TableRangeScan_7 1.00 cop[tikv] table:t2 range: decided by [test.t1.a test.t1.b], keep order:false, stats:pseudo"
]
}
]

View File

@ -446,7 +446,7 @@
},
{
"SQL": "select * from t where t.c in (select b from t s where s.a = t.a)",
"Best": "MergeSemiJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
"Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)(test.t.c,test.t.b)"
},
{
"SQL": "select t.c in (select b from t s where s.a = t.a) from t",
@ -2232,7 +2232,8 @@
"TableReader_7 2048.00 root data:Selection_6",
"└─Selection_6 2048.00 cop[tikv] eq(test.test.age, 5)",
" └─TableFullScan_5 2048.00 cop[tikv] table:test keep order:false"
]
],
"Result": null
}
]
},
@ -2245,7 +2246,8 @@
"IndexLookUp_7 2048.00 root ",
"├─IndexRangeScan_5(Build) 2048.00 cop[tikv] table:test, index:idx_age(age) range:[5,5], keep order:false",
"└─TableRowIDScan_6(Probe) 2048.00 cop[tikv] table:test keep order:false"
]
],
"Result": null
}
]
}