diff --git a/cmd/explaintest/r/explain_complex.result b/cmd/explaintest/r/explain_complex.result index 6f41bb7169ef8..36de2d89a32be 100644 --- a/cmd/explaintest/r/explain_complex.result +++ b/cmd/explaintest/r/explain_complex.result @@ -115,31 +115,31 @@ Projection_7 53.00 root test.dt.ds, test.dt.p1, test.dt.p2, test.dt.p3, test.dt. └─TableScan_15 2650.00 cop table:dt, 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, gad.t as gtime from st gad join (select id, aid, pt, dic, ip, t from dd where pt = 'android' and bm = 0 and t > 1478143908) sdk on gad.aid = sdk.aid and gad.ip = sdk.ip and sdk.t > gad.t where gad.t > 1478143908 and gad.bm = 0 and gad.pt = 'android' group by gad.aid, sdk.dic limit 2500; id count task operator info -Projection_12 1.00 root gad.id, test.dd.id, gad.aid, gad.cm, test.dd.dic, test.dd.ip, test.dd.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext, gad.t -└─Limit_15 1.00 root offset:0, count:2500 - └─HashAgg_18 1.00 root group by:gad.aid, test.dd.dic, funcs:firstrow(gad.id), firstrow(gad.aid), firstrow(gad.cm), firstrow(gad.p1), firstrow(gad.p2), firstrow(gad.p3), firstrow(gad.p4), firstrow(gad.p5), firstrow(gad.p6_md5), firstrow(gad.p7_md5), firstrow(gad.ext), firstrow(gad.t), firstrow(test.dd.id), firstrow(test.dd.dic), firstrow(test.dd.ip), firstrow(test.dd.t) - └─IndexJoin_23 0.00 root inner join, inner:IndexLookUp_22, outer key:gad.aid, inner key:test.dd.aid, other cond:eq(gad.ip, test.dd.ip), gt(test.dd.t, gad.t) - ├─IndexLookUp_32 0.00 root - │ ├─IndexScan_29 3333.33 cop table:gad, index:t, range:(1478143908,+inf], keep order:false, stats:pseudo - │ └─Selection_31 0.00 cop eq(gad.bm, 0), eq(gad.pt, "android") - │ └─TableScan_30 3333.33 cop table:st, keep order:false, stats:pseudo - └─IndexLookUp_22 0.00 root - ├─IndexScan_19 10.00 cop table:dd, index:aid, dic, range: decided by [gad.aid gad.ip], keep order:false, stats:pseudo - └─Selection_21 0.00 cop eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908) - └─TableScan_20 10.00 cop table:dd, keep order:false, stats:pseudo +Projection_13 1.00 root gad.id, test.dd.id, gad.aid, gad.cm, test.dd.dic, test.dd.ip, test.dd.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext, gad.t +└─Limit_16 1.00 root offset:0, count:2500 + └─HashAgg_19 1.00 root group by:gad.aid, test.dd.dic, funcs:firstrow(gad.id), firstrow(gad.aid), firstrow(gad.cm), firstrow(gad.p1), firstrow(gad.p2), firstrow(gad.p3), firstrow(gad.p4), firstrow(gad.p5), firstrow(gad.p6_md5), firstrow(gad.p7_md5), firstrow(gad.ext), firstrow(gad.t), firstrow(test.dd.id), firstrow(test.dd.dic), firstrow(test.dd.ip), firstrow(test.dd.t) + └─IndexJoin_24 0.00 root inner join, inner:IndexLookUp_23, outer key:gad.aid, inner key:test.dd.aid, other cond:eq(gad.ip, test.dd.ip), gt(test.dd.t, gad.t) + ├─IndexLookUp_33 0.00 root + │ ├─IndexScan_30 3333.33 cop table:gad, index:t, range:(1478143908,+inf], keep order:false, stats:pseudo + │ └─Selection_32 0.00 cop eq(gad.bm, 0), eq(gad.pt, "android") + │ └─TableScan_31 3333.33 cop table:st, keep order:false, stats:pseudo + └─IndexLookUp_23 0.00 root + ├─IndexScan_20 10.00 cop table:dd, index:aid, dic, range: decided by [gad.aid gad.ip], keep order:false, stats:pseudo + └─Selection_22 0.00 cop eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908) + └─TableScan_21 10.00 cop table:dd, 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 count task operator info -Projection_9 0.00 root gad.id, sdk.id, gad.aid, gad.cm, sdk.dic, sdk.ip, sdk.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext -└─Limit_12 0.00 root offset:0, count:3000 - └─IndexJoin_17 0.00 root inner join, inner:IndexLookUp_16, outer key:gad.aid, inner key:sdk.aid, other cond:eq(gad.dic, sdk.mac), lt(gad.t, sdk.t) - ├─IndexLookUp_26 0.00 root - │ ├─IndexScan_23 3333.33 cop table:gad, index:t, range:(1477971479,+inf], keep order:false, stats:pseudo - │ └─Selection_25 0.00 cop eq(gad.bm, 0), eq(gad.dit, "mac"), eq(gad.pt, "ios") - │ └─TableScan_24 3333.33 cop table:st, keep order:false, stats:pseudo - └─IndexLookUp_16 0.00 root - ├─IndexScan_13 10.00 cop table:sdk, index:aid, dic, range: decided by [gad.aid gad.dic], keep order:false, stats:pseudo - └─Selection_15 0.00 cop eq(sdk.bm, 0), eq(sdk.pt, "ios"), gt(sdk.t, 1477971479) - └─TableScan_14 10.00 cop table:dd, keep order:false, stats:pseudo +Projection_10 0.00 root gad.id, sdk.id, gad.aid, gad.cm, sdk.dic, sdk.ip, sdk.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext +└─Limit_13 0.00 root offset:0, count:3000 + └─IndexJoin_18 0.00 root inner join, inner:IndexLookUp_17, outer key:gad.aid, inner key:sdk.aid, other cond:eq(gad.dic, sdk.mac), lt(gad.t, sdk.t) + ├─IndexLookUp_27 0.00 root + │ ├─IndexScan_24 3333.33 cop table:gad, index:t, range:(1477971479,+inf], keep order:false, stats:pseudo + │ └─Selection_26 0.00 cop eq(gad.bm, 0), eq(gad.dit, "mac"), eq(gad.pt, "ios") + │ └─TableScan_25 3333.33 cop table:st, keep order:false, stats:pseudo + └─IndexLookUp_17 0.00 root + ├─IndexScan_14 10.00 cop table:sdk, index:aid, dic, range: decided by [gad.aid gad.dic], keep order:false, stats:pseudo + └─Selection_16 0.00 cop eq(sdk.bm, 0), eq(sdk.pt, "ios"), gt(sdk.t, 1477971479) + └─TableScan_15 10.00 cop table:dd, 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 count task 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, 3_col_0, 3_col_1 @@ -150,16 +150,16 @@ Projection_5 1.00 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st.p └─TableScan_14 250.00 cop table:st, keep order:false, stats:pseudo explain select dt.id as id, dt.aid as aid, dt.pt as pt, dt.dic as dic, dt.cm as cm, rr.gid as gid, rr.acd as acd, rr.t as t,dt.p1 as p1, dt.p2 as p2, dt.p3 as p3, dt.p4 as p4, dt.p5 as p5, dt.p6_md5 as p6, dt.p7_md5 as p7 from dt dt join rr rr on (rr.pt = 'ios' and rr.t > 1478185592 and dt.aid = rr.aid and dt.dic = rr.dic) where dt.pt = 'ios' and dt.t > 1478185592 and dt.bm = 0 limit 2000; id count task operator info -Projection_9 0.00 root dt.id, dt.aid, dt.pt, dt.dic, dt.cm, rr.gid, rr.acd, rr.t, dt.p1, dt.p2, dt.p3, dt.p4, dt.p5, dt.p6_md5, dt.p7_md5 -└─Limit_12 0.00 root offset:0, count:2000 - └─IndexJoin_18 0.00 root inner join, inner:IndexLookUp_17, outer key:dt.aid, dt.dic, inner key:rr.aid, rr.dic - ├─TableReader_42 0.00 root data:Selection_41 - │ └─Selection_41 0.00 cop eq(dt.bm, 0), eq(dt.pt, "ios"), gt(dt.t, 1478185592) - │ └─TableScan_40 10000.00 cop table:dt, range:[0,+inf], keep order:false, stats:pseudo - └─IndexLookUp_17 3.33 root - ├─IndexScan_14 10.00 cop table:rr, index:aid, dic, range: decided by [dt.aid dt.dic], keep order:false, stats:pseudo - └─Selection_16 3.33 cop eq(rr.pt, "ios"), gt(rr.t, 1478185592) - └─TableScan_15 10.00 cop table:rr, keep order:false, stats:pseudo +Projection_10 0.00 root dt.id, dt.aid, dt.pt, dt.dic, dt.cm, rr.gid, rr.acd, rr.t, dt.p1, dt.p2, dt.p3, dt.p4, dt.p5, dt.p6_md5, dt.p7_md5 +└─Limit_13 0.00 root offset:0, count:2000 + └─IndexJoin_19 0.00 root inner join, inner:IndexLookUp_18, outer key:dt.aid, dt.dic, inner key:rr.aid, rr.dic + ├─TableReader_43 0.00 root data:Selection_42 + │ └─Selection_42 0.00 cop eq(dt.bm, 0), eq(dt.pt, "ios"), gt(dt.t, 1478185592) + │ └─TableScan_41 10000.00 cop table:dt, range:[0,+inf], keep order:false, stats:pseudo + └─IndexLookUp_18 3.33 root + ├─IndexScan_15 10.00 cop table:rr, index:aid, dic, range: decided by [dt.aid dt.dic], keep order:false, stats:pseudo + └─Selection_17 3.33 cop eq(rr.pt, "ios"), gt(rr.t, 1478185592) + └─TableScan_16 10.00 cop table:rr, keep order:false, stats:pseudo explain select pc,cr,count(DISTINCT uid) as pay_users,count(oid) as pay_times,sum(am) as am from pp where ps=2 and ppt>=1478188800 and ppt<1478275200 and pi in ('510017','520017') and uid in ('18089709','18090780') group by pc,cr; id count task operator info Projection_5 1.00 root test.pp.pc, test.pp.cr, 3_col_0, 3_col_1, 3_col_2 diff --git a/cmd/explaintest/r/explain_complex_stats.result b/cmd/explaintest/r/explain_complex_stats.result index b0723109e8eb1..1569a2d3a850c 100644 --- a/cmd/explaintest/r/explain_complex_stats.result +++ b/cmd/explaintest/r/explain_complex_stats.result @@ -125,29 +125,29 @@ Projection_7 21.40 root test.dt.ds, test.dt.p1, test.dt.p2, test.dt.p3, test.dt. └─TableScan_15 128.32 cop table:dt, 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, gad.t as gtime from st gad join (select id, aid, pt, dic, ip, t from dd where pt = 'android' and bm = 0 and t > 1478143908) sdk on gad.aid = sdk.aid and gad.ip = sdk.ip and sdk.t > gad.t where gad.t > 1478143908 and gad.bm = 0 and gad.pt = 'android' group by gad.aid, sdk.dic limit 2500; id count task operator info -Projection_12 424.00 root gad.id, test.dd.id, gad.aid, gad.cm, test.dd.dic, test.dd.ip, test.dd.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext, gad.t -└─Limit_15 424.00 root offset:0, count:2500 - └─HashAgg_18 424.00 root group by:gad.aid, test.dd.dic, funcs:firstrow(gad.id), firstrow(gad.aid), firstrow(gad.cm), firstrow(gad.p1), firstrow(gad.p2), firstrow(gad.p3), firstrow(gad.p4), firstrow(gad.p5), firstrow(gad.p6_md5), firstrow(gad.p7_md5), firstrow(gad.ext), firstrow(gad.t), firstrow(test.dd.id), firstrow(test.dd.dic), firstrow(test.dd.ip), firstrow(test.dd.t) - └─IndexJoin_23 424.00 root inner join, inner:IndexLookUp_22, outer key:gad.aid, inner key:test.dd.aid, other cond:eq(gad.ip, test.dd.ip), gt(test.dd.t, gad.t) - ├─TableReader_28 424.00 root data:Selection_27 - │ └─Selection_27 424.00 cop eq(gad.bm, 0), eq(gad.pt, "android"), gt(gad.t, 1478143908) - │ └─TableScan_26 1999.00 cop table:gad, range:[0,+inf], keep order:false - └─IndexLookUp_22 455.80 root - ├─IndexScan_19 1.00 cop table:dd, index:aid, dic, range: decided by [gad.aid gad.ip], keep order:false - └─Selection_21 455.80 cop eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908) - └─TableScan_20 1.00 cop table:dd, keep order:false +Projection_13 424.00 root gad.id, test.dd.id, gad.aid, gad.cm, test.dd.dic, test.dd.ip, test.dd.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext, gad.t +└─Limit_16 424.00 root offset:0, count:2500 + └─HashAgg_19 424.00 root group by:gad.aid, test.dd.dic, funcs:firstrow(gad.id), firstrow(gad.aid), firstrow(gad.cm), firstrow(gad.p1), firstrow(gad.p2), firstrow(gad.p3), firstrow(gad.p4), firstrow(gad.p5), firstrow(gad.p6_md5), firstrow(gad.p7_md5), firstrow(gad.ext), firstrow(gad.t), firstrow(test.dd.id), firstrow(test.dd.dic), firstrow(test.dd.ip), firstrow(test.dd.t) + └─IndexJoin_24 424.00 root inner join, inner:IndexLookUp_23, outer key:gad.aid, inner key:test.dd.aid, other cond:eq(gad.ip, test.dd.ip), gt(test.dd.t, gad.t) + ├─TableReader_29 424.00 root data:Selection_28 + │ └─Selection_28 424.00 cop eq(gad.bm, 0), eq(gad.pt, "android"), gt(gad.t, 1478143908) + │ └─TableScan_27 1999.00 cop table:gad, range:[0,+inf], keep order:false + └─IndexLookUp_23 455.80 root + ├─IndexScan_20 1.00 cop table:dd, index:aid, dic, range: decided by [gad.aid gad.ip], keep order:false + └─Selection_22 455.80 cop eq(test.dd.bm, 0), eq(test.dd.pt, "android"), gt(test.dd.t, 1478143908) + └─TableScan_21 1.00 cop table:dd, 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 count task operator info -Projection_9 170.34 root gad.id, sdk.id, gad.aid, gad.cm, sdk.dic, sdk.ip, sdk.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext -└─Limit_12 170.34 root offset:0, count:3000 - └─IndexJoin_17 170.34 root inner join, inner:IndexLookUp_16, outer key:gad.aid, inner key:sdk.aid, other cond:eq(gad.dic, sdk.mac), lt(gad.t, sdk.t) - ├─TableReader_22 170.34 root data:Selection_21 - │ └─Selection_21 170.34 cop eq(gad.bm, 0), eq(gad.dit, "mac"), eq(gad.pt, "ios"), gt(gad.t, 1477971479) - │ └─TableScan_20 1999.00 cop table:gad, range:[0,+inf], keep order:false - └─IndexLookUp_16 509.04 root - ├─IndexScan_13 1.00 cop table:sdk, index:aid, dic, range: decided by [gad.aid gad.dic], keep order:false - └─Selection_15 509.04 cop eq(sdk.bm, 0), eq(sdk.pt, "ios"), gt(sdk.t, 1477971479) - └─TableScan_14 1.00 cop table:dd, keep order:false +Projection_10 170.34 root gad.id, sdk.id, gad.aid, gad.cm, sdk.dic, sdk.ip, sdk.t, gad.p1, gad.p2, gad.p3, gad.p4, gad.p5, gad.p6_md5, gad.p7_md5, gad.ext +└─Limit_13 170.34 root offset:0, count:3000 + └─IndexJoin_18 170.34 root inner join, inner:IndexLookUp_17, outer key:gad.aid, inner key:sdk.aid, other cond:eq(gad.dic, sdk.mac), lt(gad.t, sdk.t) + ├─TableReader_23 170.34 root data:Selection_22 + │ └─Selection_22 170.34 cop eq(gad.bm, 0), eq(gad.dit, "mac"), eq(gad.pt, "ios"), gt(gad.t, 1477971479) + │ └─TableScan_21 1999.00 cop table:gad, range:[0,+inf], keep order:false + └─IndexLookUp_17 509.04 root + ├─IndexScan_14 1.00 cop table:sdk, index:aid, dic, range: decided by [gad.aid gad.dic], keep order:false + └─Selection_16 509.04 cop eq(sdk.bm, 0), eq(sdk.pt, "ios"), gt(sdk.t, 1477971479) + └─TableScan_15 1.00 cop table:dd, 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 count task 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, 3_col_0, 3_col_1 @@ -158,16 +158,16 @@ Projection_5 39.28 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st. └─TableScan_14 160.23 cop table:st, keep order:false explain select dt.id as id, dt.aid as aid, dt.pt as pt, dt.dic as dic, dt.cm as cm, rr.gid as gid, rr.acd as acd, rr.t as t,dt.p1 as p1, dt.p2 as p2, dt.p3 as p3, dt.p4 as p4, dt.p5 as p5, dt.p6_md5 as p6, dt.p7_md5 as p7 from dt dt join rr rr on (rr.pt = 'ios' and rr.t > 1478185592 and dt.aid = rr.aid and dt.dic = rr.dic) where dt.pt = 'ios' and dt.t > 1478185592 and dt.bm = 0 limit 2000; id count task operator info -Projection_9 428.32 root dt.id, dt.aid, dt.pt, dt.dic, dt.cm, rr.gid, rr.acd, rr.t, dt.p1, dt.p2, dt.p3, dt.p4, dt.p5, dt.p6_md5, dt.p7_md5 -└─Limit_12 428.32 root offset:0, count:2000 - └─IndexJoin_18 428.32 root inner join, inner:IndexLookUp_17, outer key:dt.aid, dt.dic, inner key:rr.aid, rr.dic - ├─TableReader_42 428.32 root data:Selection_41 - │ └─Selection_41 428.32 cop eq(dt.bm, 0), eq(dt.pt, "ios"), gt(dt.t, 1478185592) - │ └─TableScan_40 2000.00 cop table:dt, range:[0,+inf], keep order:false - └─IndexLookUp_17 970.00 root - ├─IndexScan_14 1.00 cop table:rr, index:aid, dic, range: decided by [dt.aid dt.dic], keep order:false - └─Selection_16 970.00 cop eq(rr.pt, "ios"), gt(rr.t, 1478185592) - └─TableScan_15 1.00 cop table:rr, keep order:false +Projection_10 428.32 root dt.id, dt.aid, dt.pt, dt.dic, dt.cm, rr.gid, rr.acd, rr.t, dt.p1, dt.p2, dt.p3, dt.p4, dt.p5, dt.p6_md5, dt.p7_md5 +└─Limit_13 428.32 root offset:0, count:2000 + └─IndexJoin_19 428.32 root inner join, inner:IndexLookUp_18, outer key:dt.aid, dt.dic, inner key:rr.aid, rr.dic + ├─TableReader_43 428.32 root data:Selection_42 + │ └─Selection_42 428.32 cop eq(dt.bm, 0), eq(dt.pt, "ios"), gt(dt.t, 1478185592) + │ └─TableScan_41 2000.00 cop table:dt, range:[0,+inf], keep order:false + └─IndexLookUp_18 970.00 root + ├─IndexScan_15 1.00 cop table:rr, index:aid, dic, range: decided by [dt.aid dt.dic], keep order:false + └─Selection_17 970.00 cop eq(rr.pt, "ios"), gt(rr.t, 1478185592) + └─TableScan_16 1.00 cop table:rr, keep order:false explain select pc,cr,count(DISTINCT uid) as pay_users,count(oid) as pay_times,sum(am) as am from pp where ps=2 and ppt>=1478188800 and ppt<1478275200 and pi in ('510017','520017') and uid in ('18089709','18090780') group by pc,cr; id count task operator info Projection_5 207.86 root test.pp.pc, test.pp.cr, 3_col_0, 3_col_1, 3_col_2 diff --git a/cmd/explaintest/r/explain_easy.result b/cmd/explaintest/r/explain_easy.result index 1630f426f66ad..0a4a8683215b6 100644 --- a/cmd/explaintest/r/explain_easy.result +++ b/cmd/explaintest/r/explain_easy.result @@ -60,12 +60,12 @@ explain select count(b.c2) from t1 a, t2 b where a.c1 = b.c2 group by a.c1; id count task operator info Projection_11 10000.00 root cast(join_agg_0) └─IndexJoin_14 10000.00 root inner join, inner:TableReader_13, outer key:b.c2, inner key:a.c1 - ├─TableReader_13 10.00 root data:TableScan_12 - │ └─TableScan_12 10.00 cop table:a, range: decided by [b.c2], keep order:false, stats:pseudo - └─HashAgg_21 8000.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) - └─TableReader_22 8000.00 root data:HashAgg_17 - └─HashAgg_17 8000.00 cop group by:b.c2, funcs:count(b.c2), firstrow(b.c2) - └─TableScan_20 10000.00 cop table:b, range:[-inf,+inf], keep order:false, stats:pseudo + ├─HashAgg_21 8000.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) + │ └─TableReader_22 8000.00 root data:HashAgg_17 + │ └─HashAgg_17 8000.00 cop group by:b.c2, funcs:count(b.c2), firstrow(b.c2) + │ └─TableScan_20 10000.00 cop table:b, range:[-inf,+inf], keep order:false, stats:pseudo + └─TableReader_13 10.00 root data:TableScan_12 + └─TableScan_12 10.00 cop table:a, range: decided by [b.c2], keep order:false, stats:pseudo explain select * from t2 order by t2.c2 limit 0, 1; id count task operator info TopN_7 1.00 root test.t2.c2:asc, offset:0, count:1 @@ -94,14 +94,14 @@ StreamAgg_12 1.00 root funcs:sum(5_aux_0) └─IndexScan_22 10000.00 cop table:t2, index:c1, range:[NULL,+inf], keep order:true, stats:pseudo explain select c1 from t1 where c1 in (select c2 from t2); id count task operator info -Projection_8 10000.00 root test.t1.c1 -└─IndexJoin_11 10000.00 root inner join, inner:TableReader_10, outer key:test.t2.c2, inner key:test.t1.c1 - ├─TableReader_10 10.00 root data:TableScan_9 - │ └─TableScan_9 10.00 cop table:t1, range: decided by [test.t2.c2], keep order:false, stats:pseudo - └─HashAgg_18 8000.00 root group by:col_1, funcs:firstrow(col_0) - └─TableReader_19 8000.00 root data:HashAgg_14 - └─HashAgg_14 8000.00 cop group by:test.t2.c2, funcs:firstrow(test.t2.c2) - └─TableScan_17 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo +Projection_9 10000.00 root test.t1.c1 +└─IndexJoin_12 10000.00 root inner join, inner:TableReader_11, outer key:test.t2.c2, inner key:test.t1.c1 + ├─HashAgg_19 8000.00 root group by:col_1, funcs:firstrow(col_0) + │ └─TableReader_20 8000.00 root data:HashAgg_15 + │ └─HashAgg_15 8000.00 cop group by:test.t2.c2, funcs:firstrow(test.t2.c2) + │ └─TableScan_18 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo + └─TableReader_11 10.00 root data:TableScan_10 + └─TableScan_10 10.00 cop table:t1, range: decided by [test.t2.c2], keep order:false, stats:pseudo explain select (select count(1) k from t1 s where s.c1 = t1.c1 having k != 0) from t1; id count task operator info Projection_12 10000.00 root k @@ -466,13 +466,13 @@ HashRightJoin_7 6656.67 root right outer join, inner:TableReader_10, equal:[eq(t └─TableScan_11 10000.00 cop table:tb, range:[-inf,+inf], keep order:false, stats:pseudo explain select * from t ta inner join t tb on ta.nb = tb.nb and ta.a > 1 where ifnull(tb.nb, 1) or tb.nb is null; id count task operator info -HashRightJoin_8 4166.67 root inner join, inner:TableReader_11, equal:[eq(ta.nb, tb.nb)] -├─TableReader_11 3333.33 root data:Selection_10 -│ └─Selection_10 3333.33 cop gt(ta.a, 1) -│ └─TableScan_9 10000.00 cop table:ta, range:[-inf,+inf], keep order:false, stats:pseudo -└─TableReader_14 6656.67 root data:Selection_13 - └─Selection_13 6656.67 cop or(tb.nb, isnull(tb.nb)) - └─TableScan_12 10000.00 cop table:tb, range:[-inf,+inf], keep order:false, stats:pseudo +HashRightJoin_9 4166.67 root inner join, inner:TableReader_12, equal:[eq(ta.nb, tb.nb)] +├─TableReader_12 3333.33 root data:Selection_11 +│ └─Selection_11 3333.33 cop gt(ta.a, 1) +│ └─TableScan_10 10000.00 cop table:ta, range:[-inf,+inf], keep order:false, stats:pseudo +└─TableReader_15 6656.67 root data:Selection_14 + └─Selection_14 6656.67 cop or(tb.nb, isnull(tb.nb)) + └─TableScan_13 10000.00 cop table:tb, range:[-inf,+inf], keep order:false, stats:pseudo explain select ifnull(t.nc, 1) in (select count(*) from t s , t t1 where s.a = t.a and s.a = t1.a) from t; id count task operator info Projection_12 10000.00 root 9_aux_0 @@ -480,15 +480,15 @@ Projection_12 10000.00 root 9_aux_0 ├─TableReader_16 10000.00 root data:TableScan_15 │ └─TableScan_15 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo └─HashAgg_19 1.00 root funcs:count(join_agg_0) - └─HashLeftJoin_20 8000.00 root inner join, inner:HashAgg_30, equal:[eq(s.a, t1.a)] - ├─TableReader_24 8000.00 root data:Selection_23 - │ └─Selection_23 8000.00 cop eq(s.a, test.t.a) - │ └─TableScan_22 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo - └─HashAgg_30 6400.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) - └─TableReader_31 6400.00 root data:HashAgg_25 - └─HashAgg_25 6400.00 cop group by:t1.a, funcs:count(1), firstrow(t1.a) - └─Selection_29 8000.00 cop eq(t1.a, test.t.a) - └─TableScan_28 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo + └─HashRightJoin_21 8000.00 root inner join, inner:HashAgg_27, equal:[eq(t1.a, s.a)] + ├─HashAgg_27 6400.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) + │ └─TableReader_28 6400.00 root data:HashAgg_22 + │ └─HashAgg_22 6400.00 cop group by:t1.a, funcs:count(1), firstrow(t1.a) + │ └─Selection_26 8000.00 cop eq(t1.a, test.t.a) + │ └─TableScan_25 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo + └─TableReader_34 8000.00 root data:Selection_33 + └─Selection_33 8000.00 cop eq(s.a, test.t.a) + └─TableScan_32 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo explain select * from t ta left outer join t tb on ta.nb = tb.nb and ta.a > 1 where ifnull(tb.a, 1) or tb.a is null; id count task operator info Selection_7 10000.00 root or(ifnull(tb.a, 1), isnull(tb.a)) @@ -514,15 +514,15 @@ Projection_14 10000.00 root 9_aux_0 │ └─TableReader_19 10000.00 root data:TableScan_18 │ └─TableScan_18 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo └─HashAgg_23 1.00 root funcs:count(join_agg_0) - └─HashLeftJoin_24 8000.00 root inner join, inner:HashAgg_34, equal:[eq(s.a, t1.a)] - ├─TableReader_28 8000.00 root data:Selection_27 - │ └─Selection_27 8000.00 cop eq(s.a, test.t.a) - │ └─TableScan_26 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo - └─HashAgg_34 6400.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) - └─TableReader_35 6400.00 root data:HashAgg_29 - └─HashAgg_29 6400.00 cop group by:t1.a, funcs:count(1), firstrow(t1.a) - └─Selection_33 8000.00 cop eq(t1.a, test.t.a) - └─TableScan_32 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo + └─HashRightJoin_25 8000.00 root inner join, inner:HashAgg_31, equal:[eq(t1.a, s.a)] + ├─HashAgg_31 6400.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) + │ └─TableReader_32 6400.00 root data:HashAgg_26 + │ └─HashAgg_26 6400.00 cop group by:t1.a, funcs:count(1), firstrow(t1.a) + │ └─Selection_30 8000.00 cop eq(t1.a, test.t.a) + │ └─TableScan_29 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo + └─TableReader_38 8000.00 root data:Selection_37 + └─Selection_37 8000.00 cop eq(s.a, test.t.a) + └─TableScan_36 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo drop table if exists t; create table t(a int); explain select * from t where _tidb_rowid = 0; diff --git a/cmd/explaintest/r/explain_easy_stats.result b/cmd/explaintest/r/explain_easy_stats.result index 18b351916ff89..12cdb96b29f03 100644 --- a/cmd/explaintest/r/explain_easy_stats.result +++ b/cmd/explaintest/r/explain_easy_stats.result @@ -66,12 +66,12 @@ explain select count(b.c2) from t1 a, t2 b where a.c1 = b.c2 group by a.c1; id count task operator info Projection_11 1985.00 root cast(join_agg_0) └─IndexJoin_14 1985.00 root inner join, inner:TableReader_13, outer key:b.c2, inner key:a.c1 - ├─TableReader_13 1.00 root data:TableScan_12 - │ └─TableScan_12 1.00 cop table:a, range: decided by [b.c2], keep order:false - └─HashAgg_21 1985.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) - └─TableReader_22 1985.00 root data:HashAgg_17 - └─HashAgg_17 1985.00 cop group by:b.c2, funcs:count(b.c2), firstrow(b.c2) - └─TableScan_20 1985.00 cop table:b, range:[-inf,+inf], keep order:false + ├─HashAgg_21 1985.00 root group by:col_2, funcs:count(col_0), firstrow(col_1) + │ └─TableReader_22 1985.00 root data:HashAgg_17 + │ └─HashAgg_17 1985.00 cop group by:b.c2, funcs:count(b.c2), firstrow(b.c2) + │ └─TableScan_20 1985.00 cop table:b, range:[-inf,+inf], keep order:false + └─TableReader_13 1.00 root data:TableScan_12 + └─TableScan_12 1.00 cop table:a, range: decided by [b.c2], keep order:false explain select * from t2 order by t2.c2 limit 0, 1; id count task operator info TopN_7 1.00 root test.t2.c2:asc, offset:0, count:1 @@ -92,14 +92,14 @@ TableReader_7 0.50 root data:Selection_6 └─TableScan_5 1.00 cop table:t1, range:[1,1], keep order:false explain select c1 from t1 where c1 in (select c2 from t2); id count task operator info -Projection_8 1985.00 root test.t1.c1 -└─IndexJoin_11 1985.00 root inner join, inner:TableReader_10, outer key:test.t2.c2, inner key:test.t1.c1 - ├─TableReader_10 1.00 root data:TableScan_9 - │ └─TableScan_9 1.00 cop table:t1, range: decided by [test.t2.c2], keep order:false - └─HashAgg_18 1985.00 root group by:col_1, funcs:firstrow(col_0) - └─TableReader_19 1985.00 root data:HashAgg_14 - └─HashAgg_14 1985.00 cop group by:test.t2.c2, funcs:firstrow(test.t2.c2) - └─TableScan_17 1985.00 cop table:t2, range:[-inf,+inf], keep order:false +Projection_9 1985.00 root test.t1.c1 +└─IndexJoin_12 1985.00 root inner join, inner:TableReader_11, outer key:test.t2.c2, inner key:test.t1.c1 + ├─HashAgg_19 1985.00 root group by:col_1, funcs:firstrow(col_0) + │ └─TableReader_20 1985.00 root data:HashAgg_15 + │ └─HashAgg_15 1985.00 cop group by:test.t2.c2, funcs:firstrow(test.t2.c2) + │ └─TableScan_18 1985.00 cop table:t2, range:[-inf,+inf], keep order:false + └─TableReader_11 1.00 root data:TableScan_10 + └─TableScan_10 1.00 cop table:t1, range: decided by [test.t2.c2], keep order:false explain select * from information_schema.columns; id count task operator info MemTableScan_4 10000.00 root diff --git a/cmd/explaintest/r/topn_push_down.result b/cmd/explaintest/r/topn_push_down.result index 65992f23cfadd..4651bb89ac6b2 100644 --- a/cmd/explaintest/r/topn_push_down.result +++ b/cmd/explaintest/r/topn_push_down.result @@ -167,19 +167,19 @@ te.expect_time BETWEEN '2018-04-23 00:00:00.0' AND '2018-04-23 23:59:59.0' ORDER BY te.expect_time asc LIMIT 0, 5; id count task operator info -Projection_12 0.00 root te.expect_time -└─Limit_18 0.00 root offset:0, count:5 - └─IndexJoin_136 0.00 root left outer join, inner:IndexReader_135, outer key:tr.id, inner key:p.relate_id - ├─TopN_139 0.00 root te.expect_time:asc, offset:0, count:5 - │ └─IndexJoin_34 0.00 root inner join, inner:IndexLookUp_33, outer key:tr.id, inner key:te.trade_id - │ ├─IndexLookUp_104 0.00 root - │ │ ├─Selection_102 0.00 cop eq(tr.business_type, 18), in(tr.trade_type, 1) - │ │ │ └─IndexScan_100 10.00 cop table:tr, index:shop_identy, trade_status, business_type, trade_pay_status, trade_type, delivery_type, source, biz_date, range:[810094178,810094178], keep order:false, stats:pseudo - │ │ └─Selection_103 0.00 cop eq(tr.brand_identy, 32314), eq(tr.domain_type, 2) - │ │ └─TableScan_101 0.00 cop table:tr, keep order:false - │ └─IndexLookUp_33 250.00 root - │ ├─IndexScan_30 10.00 cop table:te, index:trade_id, range: decided by [tr.id], keep order:false, stats:pseudo - │ └─Selection_32 250.00 cop ge(te.expect_time, 2018-04-23 00:00:00.000000), le(te.expect_time, 2018-04-23 23:59:59.000000) - │ └─TableScan_31 10.00 cop table:te, keep order:false, stats:pseudo - └─IndexReader_135 10.00 root index:IndexScan_134 - └─IndexScan_134 10.00 cop table:p, index:relate_id, range: decided by [tr.id], keep order:false, stats:pseudo +Projection_13 0.00 root te.expect_time +└─Limit_19 0.00 root offset:0, count:5 + └─IndexJoin_137 0.00 root left outer join, inner:IndexReader_136, outer key:tr.id, inner key:p.relate_id + ├─TopN_140 0.00 root te.expect_time:asc, offset:0, count:5 + │ └─IndexJoin_35 0.00 root inner join, inner:IndexLookUp_34, outer key:tr.id, inner key:te.trade_id + │ ├─IndexLookUp_105 0.00 root + │ │ ├─Selection_103 0.00 cop eq(tr.business_type, 18), in(tr.trade_type, 1) + │ │ │ └─IndexScan_101 10.00 cop table:tr, index:shop_identy, trade_status, business_type, trade_pay_status, trade_type, delivery_type, source, biz_date, range:[810094178,810094178], keep order:false, stats:pseudo + │ │ └─Selection_104 0.00 cop eq(tr.brand_identy, 32314), eq(tr.domain_type, 2) + │ │ └─TableScan_102 0.00 cop table:tr, keep order:false + │ └─IndexLookUp_34 250.00 root + │ ├─IndexScan_31 10.00 cop table:te, index:trade_id, range: decided by [tr.id], keep order:false, stats:pseudo + │ └─Selection_33 250.00 cop ge(te.expect_time, 2018-04-23 00:00:00.000000), le(te.expect_time, 2018-04-23 23:59:59.000000) + │ └─TableScan_32 10.00 cop table:te, keep order:false, stats:pseudo + └─IndexReader_136 10.00 root index:IndexScan_135 + └─IndexScan_135 10.00 cop table:p, index:relate_id, range: decided by [tr.id], keep order:false, stats:pseudo diff --git a/cmd/explaintest/r/tpch.result b/cmd/explaintest/r/tpch.result index cb8d8d7a4db2c..1a9320261c2b0 100644 --- a/cmd/explaintest/r/tpch.result +++ b/cmd/explaintest/r/tpch.result @@ -182,39 +182,38 @@ s_name, p_partkey limit 100; id count task operator info -Projection_34 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_37 100.00 root tpch.supplier.s_acctbal:desc, tpch.nation.n_name:asc, tpch.supplier.s_name:asc, tpch.part.p_partkey:asc, offset:0, count:100 - └─HashRightJoin_39 125109.42 root inner join, inner:HashLeftJoin_44, equal:[eq(tpch.part.p_partkey, tpch.partsupp.ps_partkey) eq(tpch.partsupp.ps_supplycost, min(ps_supplycost))] - ├─HashLeftJoin_44 125109.42 root inner join, inner:TableReader_85, equal:[eq(tpch.nation.n_regionkey, tpch.region.r_regionkey)] - │ ├─HashLeftJoin_49 625547.12 root inner join, inner:TableReader_82, equal:[eq(tpch.supplier.s_nationkey, tpch.nation.n_nationkey)] - │ │ ├─IndexJoin_53 625547.12 root inner join, inner:TableReader_52, outer key:tpch.partsupp.ps_suppkey, inner key:tpch.supplier.s_suppkey - │ │ │ ├─IndexJoin_60 625547.12 root inner join, inner:IndexLookUp_59, outer key:tpch.part.p_partkey, inner key:tpch.partsupp.ps_partkey - │ │ │ │ ├─TableReader_76 155496.00 root data:Selection_75 - │ │ │ │ │ └─Selection_75 155496.00 cop eq(tpch.part.p_size, 30), like(tpch.part.p_type, "%STEEL", 92) - │ │ │ │ │ └─TableScan_74 10000000.00 cop table:part, range:[-inf,+inf], keep order:false - │ │ │ │ └─IndexLookUp_59 1.00 root - │ │ │ │ ├─IndexScan_57 1.00 cop table:partsupp, index:PS_PARTKEY, PS_SUPPKEY, range: decided by [tpch.part.p_partkey], keep order:false - │ │ │ │ └─TableScan_58 1.00 cop table:partsupp, keep order:false - │ │ │ └─TableReader_52 1.00 root data:TableScan_51 - │ │ │ └─TableScan_51 1.00 cop table:supplier, range: decided by [tpch.partsupp.ps_suppkey], keep order:false - │ │ └─TableReader_82 25.00 root data:TableScan_81 - │ │ └─TableScan_81 25.00 cop table:nation, range:[-inf,+inf], keep order:false - │ └─TableReader_85 1.00 root data:Selection_84 - │ └─Selection_84 1.00 cop eq(tpch.region.r_name, "ASIA") - │ └─TableScan_83 5.00 cop table:region, range:[-inf,+inf], keep order:false - └─HashAgg_88 8155010.44 root group by:tpch.partsupp.ps_partkey, funcs:min(tpch.partsupp.ps_supplycost), firstrow(tpch.partsupp.ps_partkey) - └─HashRightJoin_92 8155010.44 root inner join, inner:HashRightJoin_94, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)] - ├─HashRightJoin_94 100000.00 root inner join, inner:HashRightJoin_100, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] - │ ├─HashRightJoin_100 5.00 root inner join, inner:TableReader_105, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)] - │ │ ├─TableReader_105 1.00 root data:Selection_104 - │ │ │ └─Selection_104 1.00 cop eq(tpch.region.r_name, "ASIA") - │ │ │ └─TableScan_103 5.00 cop table:region, range:[-inf,+inf], keep order:false - │ │ └─TableReader_102 25.00 root data:TableScan_101 - │ │ └─TableScan_101 25.00 cop table:nation, range:[-inf,+inf], keep order:false - │ └─TableReader_107 500000.00 root data:TableScan_106 - │ └─TableScan_106 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false - └─TableReader_109 40000000.00 root data:TableScan_108 - └─TableScan_108 40000000.00 cop table:partsupp, range:[-inf,+inf], keep order:false +Projection_36 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_39 100.00 root tpch.supplier.s_acctbal:desc, tpch.nation.n_name:asc, tpch.supplier.s_name:asc, tpch.part.p_partkey:asc, offset:0, count:100 + └─HashRightJoin_41 155496.00 root inner join, inner:HashLeftJoin_47, equal:[eq(tpch.part.p_partkey, tpch.partsupp.ps_partkey) eq(tpch.partsupp.ps_supplycost, min(ps_supplycost))] + ├─HashLeftJoin_47 155496.00 root inner join, inner:TableReader_70, equal:[eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)] + │ ├─HashRightJoin_50 8155010.44 root inner join, inner:HashRightJoin_52, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)] + │ │ ├─HashRightJoin_52 100000.00 root inner join, inner:HashRightJoin_58, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ │ │ ├─HashRightJoin_58 5.00 root inner join, inner:TableReader_63, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)] + │ │ │ │ ├─TableReader_63 1.00 root data:Selection_62 + │ │ │ │ │ └─Selection_62 1.00 cop eq(tpch.region.r_name, "ASIA") + │ │ │ │ │ └─TableScan_61 5.00 cop table:region, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_60 25.00 root data:TableScan_59 + │ │ │ │ └─TableScan_59 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ │ │ └─TableReader_65 500000.00 root data:TableScan_64 + │ │ │ └─TableScan_64 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + │ │ └─TableReader_67 40000000.00 root data:TableScan_66 + │ │ └─TableScan_66 40000000.00 cop table:partsupp, range:[-inf,+inf], keep order:false + │ └─TableReader_70 155496.00 root data:Selection_69 + │ └─Selection_69 155496.00 cop eq(tpch.part.p_size, 30), like(tpch.part.p_type, "%STEEL", 92) + │ └─TableScan_68 10000000.00 cop table:part, range:[-inf,+inf], keep order:false + └─HashAgg_73 8155010.44 root group by:tpch.partsupp.ps_partkey, funcs:min(tpch.partsupp.ps_supplycost), firstrow(tpch.partsupp.ps_partkey) + └─HashRightJoin_77 8155010.44 root inner join, inner:HashRightJoin_79, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)] + ├─HashRightJoin_79 100000.00 root inner join, inner:HashRightJoin_85, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ ├─HashRightJoin_85 5.00 root inner join, inner:TableReader_90, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)] + │ │ ├─TableReader_90 1.00 root data:Selection_89 + │ │ │ └─Selection_89 1.00 cop eq(tpch.region.r_name, "ASIA") + │ │ │ └─TableScan_88 5.00 cop table:region, range:[-inf,+inf], keep order:false + │ │ └─TableReader_87 25.00 root data:TableScan_86 + │ │ └─TableScan_86 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ └─TableReader_92 500000.00 root data:TableScan_91 + │ └─TableScan_91 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + └─TableReader_94 40000000.00 root data:TableScan_93 + └─TableScan_93 40000000.00 cop table:partsupp, range:[-inf,+inf], keep order:false /* Q3 Shipping Priority Query This query retrieves the 10 unshipped orders with the highest value. @@ -342,28 +341,28 @@ n_name order by revenue desc; id count task operator info -Sort_21 25.00 root revenue:desc -└─Projection_23 25.00 root tpch.nation.n_name, 13_col_0 - └─HashAgg_26 25.00 root group by:tpch.nation.n_name, funcs:sum(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))), firstrow(tpch.nation.n_name) - └─HashLeftJoin_31 191559655555.87 root inner join, inner:TableReader_65, equal:[eq(tpch.nation.n_regionkey, tpch.region.r_regionkey)] - ├─HashLeftJoin_36 957798277779.33 root inner join, inner:TableReader_62, equal:[eq(tpch.supplier.s_nationkey, tpch.nation.n_nationkey)] - │ ├─HashLeftJoin_43 957798277779.33 root inner join, inner:TableReader_60, equal:[eq(tpch.orders.o_orderkey, tpch.lineitem.l_orderkey) eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)] - │ │ ├─HashLeftJoin_45 236456250000.00 root inner join, inner:TableReader_58, equal:[eq(tpch.customer.c_nationkey, tpch.supplier.s_nationkey)] - │ │ │ ├─IndexJoin_49 11822812.50 root inner join, inner:TableReader_48, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey - │ │ │ │ ├─TableReader_54 11822812.50 root data:Selection_53 - │ │ │ │ │ └─Selection_53 11822812.50 cop ge(tpch.orders.o_orderdate, 1994-01-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1995-01-01) - │ │ │ │ │ └─TableScan_52 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false - │ │ │ │ └─TableReader_48 1.00 root data:TableScan_47 - │ │ │ │ └─TableScan_47 1.00 cop table:customer, range: decided by [tpch.orders.o_custkey], keep order:false - │ │ │ └─TableReader_58 500000.00 root data:TableScan_57 - │ │ │ └─TableScan_57 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false - │ │ └─TableReader_60 300005811.00 root data:TableScan_59 - │ │ └─TableScan_59 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false - │ └─TableReader_62 25.00 root data:TableScan_61 - │ └─TableScan_61 25.00 cop table:nation, range:[-inf,+inf], keep order:false - └─TableReader_65 1.00 root data:Selection_64 - └─Selection_64 1.00 cop eq(tpch.region.r_name, "MIDDLE EAST") - └─TableScan_63 5.00 cop table:region, range:[-inf,+inf], keep order:false +Sort_23 5.00 root revenue:desc +└─Projection_25 5.00 root tpch.nation.n_name, 13_col_0 + └─HashAgg_28 5.00 root group by:tpch.nation.n_name, funcs:sum(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))), firstrow(tpch.nation.n_name) + └─IndexJoin_31 11822812.50 root inner join, inner:TableReader_30, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey, other cond:eq(tpch.supplier.s_nationkey, tpch.customer.c_nationkey) + ├─IndexJoin_38 11822812.50 root inner join, inner:TableReader_37, outer key:tpch.lineitem.l_orderkey, inner key:tpch.orders.o_orderkey + │ ├─HashRightJoin_42 61163763.01 root inner join, inner:HashRightJoin_44, equal:[eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)] + │ │ ├─HashRightJoin_44 100000.00 root inner join, inner:HashRightJoin_50, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ │ │ ├─HashRightJoin_50 5.00 root inner join, inner:TableReader_55, equal:[eq(tpch.region.r_regionkey, tpch.nation.n_regionkey)] + │ │ │ │ ├─TableReader_55 1.00 root data:Selection_54 + │ │ │ │ │ └─Selection_54 1.00 cop eq(tpch.region.r_name, "MIDDLE EAST") + │ │ │ │ │ └─TableScan_53 5.00 cop table:region, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_52 25.00 root data:TableScan_51 + │ │ │ │ └─TableScan_51 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ │ │ └─TableReader_57 500000.00 root data:TableScan_56 + │ │ │ └─TableScan_56 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + │ │ └─TableReader_59 300005811.00 root data:TableScan_58 + │ │ └─TableScan_58 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false + │ └─TableReader_37 11822812.50 root data:Selection_36 + │ └─Selection_36 11822812.50 cop ge(tpch.orders.o_orderdate, 1994-01-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1995-01-01) + │ └─TableScan_35 1.00 cop table:orders, range: decided by [tpch.lineitem.l_orderkey], keep order:false + └─TableReader_30 1.00 root data:TableScan_29 + └─TableScan_29 1.00 cop table:customer, range: decided by [tpch.supplier.s_nationkey tpch.orders.o_custkey], keep order:false /* Q6 Forecasting Revenue Change Query This query quantifies the amount of revenue increase that would have resulted from eliminating certain companywide @@ -445,27 +444,27 @@ id count task operator info Sort_22 768.91 root shipping.supp_nation:asc, shipping.cust_nation:asc, shipping.l_year:asc └─Projection_24 768.91 root shipping.supp_nation, shipping.cust_nation, shipping.l_year, 14_col_0 └─HashAgg_27 768.91 root group by:shipping.cust_nation, shipping.l_year, shipping.supp_nation, funcs:sum(shipping.volume), firstrow(shipping.supp_nation), firstrow(shipping.cust_nation), firstrow(shipping.l_year) - └─Projection_28 584459.32 root n1.n_name, n2.n_name, extract("YEAR", tpch.lineitem.l_shipdate), mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)) - └─HashLeftJoin_33 584459.32 root inner join, inner:TableReader_85, equal:[eq(tpch.customer.c_nationkey, n2.n_nationkey)], other cond:or(and(eq(n1.n_name, "JAPAN"), eq(n2.n_name, "INDIA")), and(eq(n1.n_name, "INDIA"), eq(n2.n_name, "JAPAN"))) - ├─IndexJoin_37 7305741.46 root inner join, inner:TableReader_36, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey - │ ├─IndexJoin_43 7305741.46 root inner join, inner:TableReader_42, outer key:tpch.lineitem.l_orderkey, inner key:tpch.orders.o_orderkey - │ │ ├─HashLeftJoin_64 7305741.46 root inner join, inner:TableReader_78, equal:[eq(tpch.supplier.s_nationkey, n1.n_nationkey)] - │ │ │ ├─HashLeftJoin_69 91321768.29 root inner join, inner:TableReader_75, equal:[eq(tpch.lineitem.l_suppkey, tpch.supplier.s_suppkey)] - │ │ │ │ ├─TableReader_73 91321768.29 root data:Selection_72 - │ │ │ │ │ └─Selection_72 91321768.29 cop ge(tpch.lineitem.l_shipdate, 1995-01-01 00:00:00.000000), le(tpch.lineitem.l_shipdate, 1996-12-31 00:00:00.000000) - │ │ │ │ │ └─TableScan_71 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false - │ │ │ │ └─TableReader_75 500000.00 root data:TableScan_74 - │ │ │ │ └─TableScan_74 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false - │ │ │ └─TableReader_78 2.00 root data:Selection_77 - │ │ │ └─Selection_77 2.00 cop or(eq(n1.n_name, "JAPAN"), eq(n1.n_name, "INDIA")) - │ │ │ └─TableScan_76 25.00 cop table:n1, range:[-inf,+inf], keep order:false + └─Projection_28 1957240.42 root n1.n_name, n2.n_name, extract("YEAR", tpch.lineitem.l_shipdate), mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)) + └─HashLeftJoin_33 1957240.42 root inner join, inner:TableReader_68, equal:[eq(tpch.customer.c_nationkey, n2.n_nationkey)], other cond:or(and(eq(n1.n_name, "JAPAN"), eq(n2.n_name, "INDIA")), and(eq(n1.n_name, "INDIA"), eq(n2.n_name, "JAPAN"))) + ├─IndexJoin_37 24465505.20 root inner join, inner:TableReader_36, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey + │ ├─IndexJoin_43 24465505.20 root inner join, inner:TableReader_42, outer key:tpch.lineitem.l_orderkey, inner key:tpch.orders.o_orderkey + │ │ ├─HashRightJoin_47 24465505.20 root inner join, inner:HashRightJoin_53, equal:[eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)] + │ │ │ ├─HashRightJoin_53 40000.00 root inner join, inner:TableReader_58, equal:[eq(n1.n_nationkey, tpch.supplier.s_nationkey)] + │ │ │ │ ├─TableReader_58 2.00 root data:Selection_57 + │ │ │ │ │ └─Selection_57 2.00 cop or(eq(n1.n_name, "JAPAN"), eq(n1.n_name, "INDIA")) + │ │ │ │ │ └─TableScan_56 25.00 cop table:n1, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_55 500000.00 root data:TableScan_54 + │ │ │ │ └─TableScan_54 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + │ │ │ └─TableReader_61 91321768.29 root data:Selection_60 + │ │ │ └─Selection_60 91321768.29 cop ge(tpch.lineitem.l_shipdate, 1995-01-01 00:00:00.000000), le(tpch.lineitem.l_shipdate, 1996-12-31 00:00:00.000000) + │ │ │ └─TableScan_59 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false │ │ └─TableReader_42 1.00 root data:TableScan_41 │ │ └─TableScan_41 1.00 cop table:orders, range: decided by [tpch.lineitem.l_orderkey], keep order:false │ └─TableReader_36 1.00 root data:TableScan_35 │ └─TableScan_35 1.00 cop table:customer, range: decided by [tpch.orders.o_custkey], keep order:false - └─TableReader_85 2.00 root data:Selection_84 - └─Selection_84 2.00 cop or(eq(n2.n_name, "INDIA"), eq(n2.n_name, "JAPAN")) - └─TableScan_83 25.00 cop table:n2, range:[-inf,+inf], keep order:false + └─TableReader_68 2.00 root data:Selection_67 + └─Selection_67 2.00 cop or(eq(n2.n_name, "INDIA"), eq(n2.n_name, "JAPAN")) + └─TableScan_66 25.00 cop table:n2, range:[-inf,+inf], keep order:false /* Q8 National Market Share Query This query determines how the market share of a given nation within a given region has changed over two years for @@ -514,37 +513,37 @@ o_year order by o_year; id count task operator info -Sort_28 718.01 root all_nations.o_year:asc -└─Projection_30 718.01 root all_nations.o_year, div(18_col_0, 18_col_1) - └─HashAgg_33 718.01 root group by:all_nations.o_year, funcs:sum(case(eq(all_nations.nation, "INDIA"), all_nations.volume, 0)), sum(all_nations.volume), firstrow(all_nations.o_year) - └─Projection_34 112469.62 root extract("YEAR", tpch.orders.o_orderdate), mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), n2.n_name - └─HashLeftJoin_39 112469.62 root inner join, inner:TableReader_103, equal:[eq(n1.n_regionkey, tpch.region.r_regionkey)] - ├─HashLeftJoin_44 562348.12 root inner join, inner:TableReader_100, equal:[eq(tpch.customer.c_nationkey, n1.n_nationkey)] - │ ├─IndexJoin_48 562348.12 root inner join, inner:TableReader_47, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey - │ │ ├─HashLeftJoin_54 562348.12 root inner join, inner:TableReader_96, equal:[eq(tpch.supplier.s_nationkey, n2.n_nationkey)] - │ │ │ ├─IndexJoin_58 562348.12 root inner join, inner:TableReader_57, outer key:tpch.lineitem.l_suppkey, inner key:tpch.supplier.s_suppkey - │ │ │ │ ├─HashLeftJoin_65 562348.12 root inner join, inner:TableReader_92, equal:[eq(tpch.lineitem.l_partkey, tpch.part.p_partkey)] - │ │ │ │ │ ├─IndexJoin_71 90661378.61 root inner join, inner:IndexLookUp_70, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey - │ │ │ │ │ │ ├─TableReader_87 22382008.93 root data:Selection_86 - │ │ │ │ │ │ │ └─Selection_86 22382008.93 cop ge(tpch.orders.o_orderdate, 1995-01-01 00:00:00.000000), le(tpch.orders.o_orderdate, 1996-12-31 00:00:00.000000) - │ │ │ │ │ │ │ └─TableScan_85 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false - │ │ │ │ │ │ └─IndexLookUp_70 1.00 root - │ │ │ │ │ │ ├─IndexScan_68 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false - │ │ │ │ │ │ └─TableScan_69 1.00 cop table:lineitem, keep order:false - │ │ │ │ │ └─TableReader_92 61674.00 root data:Selection_91 - │ │ │ │ │ └─Selection_91 61674.00 cop eq(tpch.part.p_type, "SMALL PLATED COPPER") - │ │ │ │ │ └─TableScan_90 10000000.00 cop table:part, range:[-inf,+inf], keep order:false - │ │ │ │ └─TableReader_57 1.00 root data:TableScan_56 - │ │ │ │ └─TableScan_56 1.00 cop table:supplier, range: decided by [tpch.lineitem.l_suppkey], keep order:false - │ │ │ └─TableReader_96 25.00 root data:TableScan_95 - │ │ │ └─TableScan_95 25.00 cop table:n2, range:[-inf,+inf], keep order:false - │ │ └─TableReader_47 1.00 root data:TableScan_46 - │ │ └─TableScan_46 1.00 cop table:customer, range: decided by [tpch.orders.o_custkey], keep order:false - │ └─TableReader_100 25.00 root data:TableScan_99 - │ └─TableScan_99 25.00 cop table:n1, range:[-inf,+inf], keep order:false - └─TableReader_103 1.00 root data:Selection_102 - └─Selection_102 1.00 cop eq(tpch.region.r_name, "ASIA") - └─TableScan_101 5.00 cop table:region, range:[-inf,+inf], keep order:false +Sort_29 718.01 root all_nations.o_year:asc +└─Projection_31 718.01 root all_nations.o_year, div(18_col_0, 18_col_1) + └─HashAgg_34 718.01 root group by:all_nations.o_year, funcs:sum(case(eq(all_nations.nation, "INDIA"), all_nations.volume, 0)), sum(all_nations.volume), firstrow(all_nations.o_year) + └─Projection_35 562348.12 root extract("YEAR", tpch.orders.o_orderdate), mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), n2.n_name + └─HashLeftJoin_39 562348.12 root inner join, inner:TableReader_87, equal:[eq(tpch.supplier.s_nationkey, n2.n_nationkey)] + ├─IndexJoin_43 562348.12 root inner join, inner:TableReader_42, outer key:tpch.lineitem.l_suppkey, inner key:tpch.supplier.s_suppkey + │ ├─HashLeftJoin_50 562348.12 root inner join, inner:TableReader_83, equal:[eq(tpch.lineitem.l_partkey, tpch.part.p_partkey)] + │ │ ├─IndexJoin_56 90661378.61 root inner join, inner:IndexLookUp_55, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey + │ │ │ ├─HashRightJoin_60 22382008.93 root inner join, inner:HashRightJoin_62, equal:[eq(tpch.customer.c_custkey, tpch.orders.o_custkey)] + │ │ │ │ ├─HashRightJoin_62 1500000.00 root inner join, inner:HashRightJoin_68, equal:[eq(n1.n_nationkey, tpch.customer.c_nationkey)] + │ │ │ │ │ ├─HashRightJoin_68 5.00 root inner join, inner:TableReader_73, equal:[eq(tpch.region.r_regionkey, n1.n_regionkey)] + │ │ │ │ │ │ ├─TableReader_73 1.00 root data:Selection_72 + │ │ │ │ │ │ │ └─Selection_72 1.00 cop eq(tpch.region.r_name, "ASIA") + │ │ │ │ │ │ │ └─TableScan_71 5.00 cop table:region, range:[-inf,+inf], keep order:false + │ │ │ │ │ │ └─TableReader_70 25.00 root data:TableScan_69 + │ │ │ │ │ │ └─TableScan_69 25.00 cop table:n1, range:[-inf,+inf], keep order:false + │ │ │ │ │ └─TableReader_75 7500000.00 root data:TableScan_74 + │ │ │ │ │ └─TableScan_74 7500000.00 cop table:customer, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_78 22382008.93 root data:Selection_77 + │ │ │ │ └─Selection_77 22382008.93 cop ge(tpch.orders.o_orderdate, 1995-01-01 00:00:00.000000), le(tpch.orders.o_orderdate, 1996-12-31 00:00:00.000000) + │ │ │ │ └─TableScan_76 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false + │ │ │ └─IndexLookUp_55 1.00 root + │ │ │ ├─IndexScan_53 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false + │ │ │ └─TableScan_54 1.00 cop table:lineitem, keep order:false + │ │ └─TableReader_83 61674.00 root data:Selection_82 + │ │ └─Selection_82 61674.00 cop eq(tpch.part.p_type, "SMALL PLATED COPPER") + │ │ └─TableScan_81 10000000.00 cop table:part, range:[-inf,+inf], keep order:false + │ └─TableReader_42 1.00 root data:TableScan_41 + │ └─TableScan_41 1.00 cop table:supplier, range: decided by [tpch.lineitem.l_suppkey], keep order:false + └─TableReader_87 25.00 root data:TableScan_86 + └─TableScan_86 25.00 cop table:n2, range:[-inf,+inf], keep order:false /* Q9 Product Type Profit Measure Query This query determines how much profit is made on a given line of parts, broken out by supplier nation and year. @@ -589,30 +588,29 @@ order by nation, o_year desc; id count task operator info -Sort_22 2406.00 root profit.nation:asc, profit.o_year:desc -└─Projection_23 2406.00 root profit.nation, profit.o_year, 14_col_0 - └─HashAgg_26 2406.00 root group by:profit.nation, profit.o_year, funcs:sum(profit.amount), firstrow(profit.nation), firstrow(profit.o_year) - └─Projection_27 971049283.51 root tpch.nation.n_name, extract("YEAR", tpch.orders.o_orderdate), minus(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), mul(tpch.partsupp.ps_supplycost, tpch.lineitem.l_quantity)) - └─MergeJoin_28 971049283.51 root inner join, left key:tpch.lineitem.l_orderkey, right key:tpch.orders.o_orderkey - ├─IndexJoin_37 971049283.51 root inner join, inner:IndexLookUp_36, outer key:tpch.lineitem.l_suppkey, tpch.lineitem.l_partkey, inner key:tpch.partsupp.ps_suppkey, tpch.partsupp.ps_partkey - │ ├─IndexJoin_40 241379546.70 root inner join, inner:TableReader_39, outer key:tpch.supplier.s_nationkey, inner key:tpch.nation.n_nationkey - │ │ ├─IndexJoin_43 241379546.70 root inner join, inner:TableReader_42, outer key:tpch.lineitem.l_suppkey, inner key:tpch.supplier.s_suppkey - │ │ │ ├─IndexJoin_47 241379546.70 root inner join, inner:TableReader_46, outer key:tpch.lineitem.l_partkey, inner key:tpch.part.p_partkey - │ │ │ │ ├─TableReader_46 8000000.00 root data:Selection_45 - │ │ │ │ │ └─Selection_45 8000000.00 cop like(tpch.part.p_name, "%dim%", 92) - │ │ │ │ │ └─TableScan_44 1.00 cop table:part, range: decided by [tpch.lineitem.l_partkey], keep order:false - │ │ │ │ └─IndexLookUp_51 300005811.00 root - │ │ │ │ ├─IndexScan_49 300005811.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range:[NULL,+inf], keep order:true - │ │ │ │ └─TableScan_50 300005811.00 cop table:lineitem, keep order:false - │ │ │ └─TableReader_42 1.00 root data:TableScan_41 - │ │ │ └─TableScan_41 1.00 cop table:supplier, range: decided by [tpch.lineitem.l_suppkey], keep order:false - │ │ └─TableReader_39 1.00 root data:TableScan_38 - │ │ └─TableScan_38 1.00 cop table:nation, range: decided by [tpch.supplier.s_nationkey], keep order:false - │ └─IndexLookUp_36 1.00 root - │ ├─IndexScan_34 1.00 cop table:partsupp, index:PS_PARTKEY, PS_SUPPKEY, range: decided by [tpch.lineitem.l_suppkey tpch.lineitem.l_partkey], keep order:false - │ └─TableScan_35 1.00 cop table:partsupp, keep order:false - └─TableReader_53 75000000.00 root data:TableScan_52 - └─TableScan_52 75000000.00 cop table:orders, range:[-inf,+inf], keep order:true +Sort_25 2406.00 root profit.nation:asc, profit.o_year:desc +└─Projection_26 2406.00 root profit.nation, profit.o_year, 14_col_0 + └─HashAgg_29 2406.00 root group by:profit.nation, profit.o_year, funcs:sum(profit.amount), firstrow(profit.nation), firstrow(profit.o_year) + └─Projection_30 971049283.51 root tpch.nation.n_name, extract("YEAR", tpch.orders.o_orderdate), minus(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), mul(tpch.partsupp.ps_supplycost, tpch.lineitem.l_quantity)) + └─IndexJoin_34 971049283.51 root inner join, inner:IndexLookUp_33, outer key:tpch.lineitem.l_suppkey, tpch.lineitem.l_partkey, inner key:tpch.partsupp.ps_suppkey, tpch.partsupp.ps_partkey + ├─IndexJoin_40 241379546.70 root inner join, inner:TableReader_39, outer key:tpch.lineitem.l_orderkey, inner key:tpch.orders.o_orderkey + │ ├─HashLeftJoin_51 241379546.70 root inner join, inner:TableReader_68, equal:[eq(tpch.lineitem.l_partkey, tpch.part.p_partkey)] + │ │ ├─HashRightJoin_54 300005811.00 root inner join, inner:HashRightJoin_59, equal:[eq(tpch.supplier.s_suppkey, tpch.lineitem.l_suppkey)] + │ │ │ ├─HashRightJoin_59 500000.00 root inner join, inner:TableReader_63, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ │ │ │ ├─TableReader_63 25.00 root data:TableScan_62 + │ │ │ │ │ └─TableScan_62 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_61 500000.00 root data:TableScan_60 + │ │ │ │ └─TableScan_60 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + │ │ │ └─TableReader_65 300005811.00 root data:TableScan_64 + │ │ │ └─TableScan_64 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false + │ │ └─TableReader_68 8000000.00 root data:Selection_67 + │ │ └─Selection_67 8000000.00 cop like(tpch.part.p_name, "%dim%", 92) + │ │ └─TableScan_66 10000000.00 cop table:part, range:[-inf,+inf], keep order:false + │ └─TableReader_39 1.00 root data:TableScan_38 + │ └─TableScan_38 1.00 cop table:orders, range: decided by [tpch.lineitem.l_orderkey], keep order:false + └─IndexLookUp_33 1.00 root + ├─IndexScan_31 1.00 cop table:partsupp, index:PS_PARTKEY, PS_SUPPKEY, range: decided by [tpch.lineitem.l_suppkey tpch.lineitem.l_partkey], keep order:false + └─TableScan_32 1.00 cop table:partsupp, keep order:false /* Q10 Returned Item Reporting Query The query identifies customers who might be having problems with the parts that are shipped to them. @@ -659,21 +657,21 @@ limit 20; id count task operator info Projection_17 20.00 root tpch.customer.c_custkey, tpch.customer.c_name, 9_col_0, tpch.customer.c_acctbal, tpch.nation.n_name, tpch.customer.c_address, tpch.customer.c_phone, tpch.customer.c_comment └─TopN_20 20.00 root 9_col_0:desc, offset:0, count:20 - └─HashAgg_26 7500000.00 root group by:tpch.customer.c_acctbal, tpch.customer.c_address, tpch.customer.c_comment, tpch.customer.c_custkey, tpch.customer.c_name, tpch.customer.c_phone, tpch.nation.n_name, funcs:sum(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))), firstrow(tpch.customer.c_custkey), firstrow(tpch.customer.c_name), firstrow(tpch.customer.c_address), firstrow(tpch.customer.c_phone), firstrow(tpch.customer.c_acctbal), firstrow(tpch.customer.c_comment), firstrow(tpch.nation.n_name) - └─HashLeftJoin_30 12222016.17 root inner join, inner:TableReader_66, equal:[eq(tpch.customer.c_nationkey, tpch.nation.n_nationkey)] - ├─IndexJoin_34 12222016.17 root inner join, inner:TableReader_33, outer key:tpch.orders.o_custkey, inner key:tpch.customer.c_custkey - │ ├─IndexJoin_42 12222016.17 root inner join, inner:IndexLookUp_41, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey - │ │ ├─TableReader_59 3017307.69 root data:Selection_58 - │ │ │ └─Selection_58 3017307.69 cop ge(tpch.orders.o_orderdate, 1993-08-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1993-11-01) - │ │ │ └─TableScan_57 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false - │ │ └─IndexLookUp_41 73916005.00 root - │ │ ├─IndexScan_38 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false - │ │ └─Selection_40 73916005.00 cop eq(tpch.lineitem.l_returnflag, "R") - │ │ └─TableScan_39 1.00 cop table:lineitem, keep order:false - │ └─TableReader_33 1.00 root data:TableScan_32 - │ └─TableScan_32 1.00 cop table:customer, range: decided by [tpch.orders.o_custkey], keep order:false - └─TableReader_66 25.00 root data:TableScan_65 - └─TableScan_65 25.00 cop table:nation, range:[-inf,+inf], keep order:false + └─HashAgg_26 3017307.69 root group by:tpch.customer.c_acctbal, tpch.customer.c_address, tpch.customer.c_comment, tpch.customer.c_custkey, tpch.customer.c_name, tpch.customer.c_phone, tpch.nation.n_name, funcs:sum(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))), firstrow(tpch.customer.c_custkey), firstrow(tpch.customer.c_name), firstrow(tpch.customer.c_address), firstrow(tpch.customer.c_phone), firstrow(tpch.customer.c_acctbal), firstrow(tpch.customer.c_comment), firstrow(tpch.nation.n_name) + └─IndexJoin_32 12222016.17 root inner join, inner:IndexLookUp_31, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey + ├─HashLeftJoin_35 3017307.69 root inner join, inner:TableReader_48, equal:[eq(tpch.customer.c_custkey, tpch.orders.o_custkey)] + │ ├─HashRightJoin_41 7500000.00 root inner join, inner:TableReader_45, equal:[eq(tpch.nation.n_nationkey, tpch.customer.c_nationkey)] + │ │ ├─TableReader_45 25.00 root data:TableScan_44 + │ │ │ └─TableScan_44 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ │ └─TableReader_43 7500000.00 root data:TableScan_42 + │ │ └─TableScan_42 7500000.00 cop table:customer, range:[-inf,+inf], keep order:false + │ └─TableReader_48 3017307.69 root data:Selection_47 + │ └─Selection_47 3017307.69 cop ge(tpch.orders.o_orderdate, 1993-08-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1993-11-01) + │ └─TableScan_46 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false + └─IndexLookUp_31 73916005.00 root + ├─IndexScan_28 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false + └─Selection_30 73916005.00 cop eq(tpch.lineitem.l_returnflag, "R") + └─TableScan_29 1.00 cop table:lineitem, keep order:false /* Q11 Important Stock Identification Query This query finds the most important subset of suppliers' stock in a given nation. @@ -922,9 +920,9 @@ p_brand, p_type, p_size; id count task operator info -Sort_13 14.41 root supplier_cnt:desc, tpch.part.p_brand:asc, tpch.part.p_type:asc, tpch.part.p_size:asc -└─Projection_14 14.41 root tpch.part.p_brand, tpch.part.p_type, tpch.part.p_size, 9_col_0 - └─HashAgg_17 14.41 root group by:tpch.part.p_brand, tpch.part.p_size, tpch.part.p_type, funcs:count(distinct tpch.partsupp.ps_suppkey), firstrow(tpch.part.p_brand), firstrow(tpch.part.p_type), firstrow(tpch.part.p_size) +Sort_13 3863988.24 root supplier_cnt:desc, tpch.part.p_brand:asc, tpch.part.p_type:asc, tpch.part.p_size:asc +└─Projection_14 3863988.24 root tpch.part.p_brand, tpch.part.p_type, tpch.part.p_size, 9_col_0 + └─HashAgg_17 3863988.24 root group by:tpch.part.p_brand, tpch.part.p_size, tpch.part.p_type, funcs:count(distinct tpch.partsupp.ps_suppkey), firstrow(tpch.part.p_brand), firstrow(tpch.part.p_type), firstrow(tpch.part.p_size) └─HashLeftJoin_22 3863988.24 root anti semi join, inner:TableReader_46, equal:[eq(tpch.partsupp.ps_suppkey, tpch.supplier.s_suppkey)] ├─IndexJoin_26 4829985.30 root inner join, inner:IndexReader_25, outer key:tpch.part.p_partkey, inner key:tpch.partsupp.ps_partkey │ ├─TableReader_41 1200618.43 root data:Selection_40 @@ -964,20 +962,20 @@ where l_partkey = p_partkey ); id count task operator info -Projection_14 1.00 root div(11_col_0, 7.0) -└─StreamAgg_19 1.00 root funcs:sum(tpch.lineitem.l_extendedprice) - └─Projection_42 293773.83 root tpch.lineitem.l_partkey, tpch.lineitem.l_quantity, tpch.lineitem.l_extendedprice, tpch.part.p_partkey, tpch.part.p_brand, tpch.part.p_container, mul(0.2, 7_col_0) - └─HashRightJoin_44 293773.83 root inner join, inner:HashRightJoin_28, equal:[eq(tpch.part.p_partkey, tpch.lineitem.l_partkey)], other cond:lt(tpch.lineitem.l_quantity, mul(0.2, 7_col_0)) - ├─HashRightJoin_28 293773.83 root inner join, inner:TableReader_33, equal:[eq(tpch.part.p_partkey, tpch.lineitem.l_partkey)] - │ ├─TableReader_33 9736.49 root data:Selection_32 - │ │ └─Selection_32 9736.49 cop eq(tpch.part.p_brand, "Brand#44"), eq(tpch.part.p_container, "WRAP PKG") - │ │ └─TableScan_31 10000000.00 cop table:part, range:[-inf,+inf], keep order:false - │ └─TableReader_30 300005811.00 root data:TableScan_29 - │ └─TableScan_29 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false - └─HashAgg_59 9943040.00 root group by:col_3, funcs:avg(col_0, col_1), firstrow(col_2) - └─TableReader_60 9943040.00 root data:HashAgg_56 - └─HashAgg_56 9943040.00 cop group by:tpch.lineitem.l_partkey, funcs:avg(tpch.lineitem.l_quantity), firstrow(tpch.lineitem.l_partkey) - └─TableScan_37 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false +Projection_16 1.00 root div(11_col_0, 7.0) +└─StreamAgg_21 1.00 root funcs:sum(tpch.lineitem.l_extendedprice) + └─Projection_44 293773.83 root tpch.lineitem.l_partkey, tpch.lineitem.l_quantity, tpch.lineitem.l_extendedprice, tpch.part.p_partkey, tpch.part.p_brand, tpch.part.p_container, mul(0.2, 7_col_0) + └─HashRightJoin_46 293773.83 root inner join, inner:HashRightJoin_30, equal:[eq(tpch.part.p_partkey, tpch.lineitem.l_partkey)], other cond:lt(tpch.lineitem.l_quantity, mul(0.2, 7_col_0)) + ├─HashRightJoin_30 9736.49 root inner join, inner:TableReader_41, equal:[eq(tpch.part.p_partkey, tpch.lineitem.l_partkey)] + │ ├─TableReader_41 9736.49 root data:Selection_40 + │ │ └─Selection_40 9736.49 cop eq(tpch.part.p_brand, "Brand#44"), eq(tpch.part.p_container, "WRAP PKG") + │ │ └─TableScan_39 10000000.00 cop table:part, range:[-inf,+inf], keep order:false + │ └─HashAgg_35 9943040.00 root group by:col_3, funcs:avg(col_0, col_1), firstrow(col_2) + │ └─TableReader_36 9943040.00 root data:HashAgg_31 + │ └─HashAgg_31 9943040.00 cop group by:tpch.lineitem.l_partkey, funcs:avg(tpch.lineitem.l_quantity), firstrow(tpch.lineitem.l_partkey) + │ └─TableScan_34 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false + └─TableReader_62 300005811.00 root data:TableScan_61 + └─TableScan_61 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false /* Q18 Large Volume Customer Query The Large Volume Customer Query ranks customers based on their having placed a large quantity order. Large @@ -1021,24 +1019,24 @@ o_totalprice desc, o_orderdate limit 100; id count task operator info -Projection_22 100.00 root tpch.customer.c_name, tpch.customer.c_custkey, tpch.orders.o_orderkey, tpch.orders.o_orderdate, tpch.orders.o_totalprice, 14_col_0 -└─TopN_25 100.00 root tpch.orders.o_totalprice:desc, tpch.orders.o_orderdate:asc, offset:0, count:100 - └─HashAgg_28 75000000.00 root group by:tpch.customer.c_custkey, tpch.customer.c_name, tpch.orders.o_orderdate, tpch.orders.o_orderkey, tpch.orders.o_totalprice, funcs:sum(tpch.lineitem.l_quantity), firstrow(tpch.customer.c_custkey), firstrow(tpch.customer.c_name), firstrow(tpch.orders.o_orderkey), firstrow(tpch.orders.o_totalprice), firstrow(tpch.orders.o_orderdate) - └─HashLeftJoin_29 237008981.18 root inner join, inner:Selection_58, equal:[eq(tpch.orders.o_orderkey, tpch.lineitem.l_orderkey)] - ├─IndexJoin_35 300005811.00 root inner join, inner:IndexLookUp_34, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey - │ ├─HashRightJoin_51 75000000.00 root inner join, inner:TableReader_55, equal:[eq(tpch.customer.c_custkey, tpch.orders.o_custkey)] - │ │ ├─TableReader_55 7500000.00 root data:TableScan_54 - │ │ │ └─TableScan_54 7500000.00 cop table:customer, range:[-inf,+inf], keep order:false - │ │ └─TableReader_53 75000000.00 root data:TableScan_52 - │ │ └─TableScan_52 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false - │ └─IndexLookUp_34 1.00 root - │ ├─IndexScan_32 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false - │ └─TableScan_33 1.00 cop table:lineitem, keep order:false - └─Selection_58 59251097.60 root gt(sel_agg_2, 314) - └─HashAgg_65 74063872.00 root group by:col_2, funcs:sum(col_0), firstrow(col_1) - └─TableReader_66 74063872.00 root data:HashAgg_59 - └─HashAgg_59 74063872.00 cop group by:tpch.lineitem.l_orderkey, funcs:sum(tpch.lineitem.l_quantity), firstrow(tpch.lineitem.l_orderkey) - └─TableScan_64 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false +Projection_24 100.00 root tpch.customer.c_name, tpch.customer.c_custkey, tpch.orders.o_orderkey, tpch.orders.o_orderdate, tpch.orders.o_totalprice, 14_col_0 +└─TopN_27 100.00 root tpch.orders.o_totalprice:desc, tpch.orders.o_orderdate:asc, offset:0, count:100 + └─HashAgg_30 59251097.60 root group by:tpch.customer.c_custkey, tpch.customer.c_name, tpch.orders.o_orderdate, tpch.orders.o_orderkey, tpch.orders.o_totalprice, funcs:sum(tpch.lineitem.l_quantity), firstrow(tpch.customer.c_custkey), firstrow(tpch.customer.c_name), firstrow(tpch.orders.o_orderkey), firstrow(tpch.orders.o_totalprice), firstrow(tpch.orders.o_orderdate) + └─IndexJoin_35 240004648.80 root inner join, inner:IndexLookUp_34, outer key:tpch.orders.o_orderkey, inner key:tpch.lineitem.l_orderkey + ├─HashLeftJoin_38 59251097.60 root inner join, inner:Selection_49, equal:[eq(tpch.orders.o_orderkey, tpch.lineitem.l_orderkey)] + │ ├─HashRightJoin_44 75000000.00 root inner join, inner:TableReader_48, equal:[eq(tpch.customer.c_custkey, tpch.orders.o_custkey)] + │ │ ├─TableReader_48 7500000.00 root data:TableScan_47 + │ │ │ └─TableScan_47 7500000.00 cop table:customer, range:[-inf,+inf], keep order:false + │ │ └─TableReader_46 75000000.00 root data:TableScan_45 + │ │ └─TableScan_45 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false + │ └─Selection_49 59251097.60 root gt(sel_agg_2, 314) + │ └─HashAgg_56 74063872.00 root group by:col_2, funcs:sum(col_0), firstrow(col_1) + │ └─TableReader_57 74063872.00 root data:HashAgg_50 + │ └─HashAgg_50 74063872.00 cop group by:tpch.lineitem.l_orderkey, funcs:sum(tpch.lineitem.l_quantity), firstrow(tpch.lineitem.l_orderkey) + │ └─TableScan_55 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false + └─IndexLookUp_34 1.00 root + ├─IndexScan_32 1.00 cop table:lineitem, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false + └─TableScan_33 1.00 cop table:lineitem, keep order:false /* Q19 Discounted Revenue Query The Discounted Revenue Query reports the gross discounted revenue attributed to the sale of selected parts handled @@ -1140,30 +1138,30 @@ and n_name = 'ALGERIA' order by s_name; id count task operator info -Sort_26 20000.00 root tpch.supplier.s_name:asc -└─Projection_28 20000.00 root tpch.supplier.s_name, tpch.supplier.s_address - └─HashRightJoin_30 20000.00 root inner join, inner:HashRightJoin_36, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)] - ├─HashRightJoin_36 20000.00 root inner join, inner:TableReader_41, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] - │ ├─TableReader_41 1.00 root data:Selection_40 - │ │ └─Selection_40 1.00 cop eq(tpch.nation.n_name, "ALGERIA") - │ │ └─TableScan_39 25.00 cop table:nation, range:[-inf,+inf], keep order:false - │ └─TableReader_38 500000.00 root data:TableScan_37 - │ └─TableScan_37 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false - └─HashAgg_44 257492.04 root group by:tpch.partsupp.ps_suppkey, funcs:firstrow(tpch.partsupp.ps_suppkey) - └─Projection_45 257492.04 root tpch.partsupp.ps_partkey, tpch.partsupp.ps_suppkey, tpch.partsupp.ps_availqty, tpch.part.p_partkey, mul(0.5, 14_col_0) - └─Selection_46 257492.04 root gt(cast(tpch.partsupp.ps_availqty), mul(0.5, 14_col_0)) - └─HashAgg_49 321865.05 root group by:tpch.partsupp.ps_partkey, tpch.partsupp.ps_suppkey, funcs:firstrow(tpch.partsupp.ps_partkey), firstrow(tpch.partsupp.ps_suppkey), firstrow(tpch.partsupp.ps_availqty), firstrow(tpch.part.p_partkey), sum(tpch.lineitem.l_quantity) - └─HashLeftJoin_52 9711455.06 root left outer join, inner:TableReader_78, equal:[eq(tpch.partsupp.ps_partkey, tpch.lineitem.l_partkey) eq(tpch.partsupp.ps_suppkey, tpch.lineitem.l_suppkey)] - ├─IndexJoin_61 321865.05 root inner join, inner:IndexLookUp_60, outer key:tpch.part.p_partkey, inner key:tpch.partsupp.ps_partkey - │ ├─IndexLookUp_60 1.00 root - │ │ ├─IndexScan_58 1.00 cop table:partsupp, index:PS_PARTKEY, PS_SUPPKEY, range: decided by [tpch.part.p_partkey], keep order:false - │ │ └─TableScan_59 1.00 cop table:partsupp, keep order:false - │ └─TableReader_73 80007.93 root data:Selection_72 - │ └─Selection_72 80007.93 cop like(tpch.part.p_name, "green%", 92) - │ └─TableScan_71 10000000.00 cop table:part, range:[-inf,+inf], keep order:false - └─TableReader_78 44189356.65 root data:Selection_77 - └─Selection_77 44189356.65 cop ge(tpch.lineitem.l_shipdate, 1993-01-01 00:00:00.000000), lt(tpch.lineitem.l_shipdate, 1994-01-01) - └─TableScan_76 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false +Sort_28 20000.00 root tpch.supplier.s_name:asc +└─Projection_30 20000.00 root tpch.supplier.s_name, tpch.supplier.s_address + └─HashRightJoin_32 20000.00 root inner join, inner:HashRightJoin_38, equal:[eq(tpch.supplier.s_suppkey, tpch.partsupp.ps_suppkey)] + ├─HashRightJoin_38 20000.00 root inner join, inner:TableReader_43, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ ├─TableReader_43 1.00 root data:Selection_42 + │ │ └─Selection_42 1.00 cop eq(tpch.nation.n_name, "ALGERIA") + │ │ └─TableScan_41 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ └─TableReader_40 500000.00 root data:TableScan_39 + │ └─TableScan_39 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + └─HashAgg_46 64006.34 root group by:tpch.partsupp.ps_suppkey, funcs:firstrow(tpch.partsupp.ps_suppkey) + └─Projection_47 64006.34 root tpch.partsupp.ps_partkey, tpch.partsupp.ps_suppkey, tpch.partsupp.ps_availqty, tpch.part.p_partkey, mul(0.5, 14_col_0) + └─Selection_48 64006.34 root gt(cast(tpch.partsupp.ps_availqty), mul(0.5, 14_col_0)) + └─HashAgg_51 80007.93 root group by:tpch.partsupp.ps_partkey, tpch.partsupp.ps_suppkey, funcs:firstrow(tpch.partsupp.ps_partkey), firstrow(tpch.partsupp.ps_suppkey), firstrow(tpch.partsupp.ps_availqty), firstrow(tpch.part.p_partkey), sum(tpch.lineitem.l_quantity) + └─HashLeftJoin_54 9711455.06 root left outer join, inner:TableReader_80, equal:[eq(tpch.partsupp.ps_partkey, tpch.lineitem.l_partkey) eq(tpch.partsupp.ps_suppkey, tpch.lineitem.l_suppkey)] + ├─IndexJoin_59 321865.05 root inner join, inner:IndexLookUp_58, outer key:tpch.part.p_partkey, inner key:tpch.partsupp.ps_partkey + │ ├─TableReader_75 80007.93 root data:Selection_74 + │ │ └─Selection_74 80007.93 cop like(tpch.part.p_name, "green%", 92) + │ │ └─TableScan_73 10000000.00 cop table:part, range:[-inf,+inf], keep order:false + │ └─IndexLookUp_58 1.00 root + │ ├─IndexScan_56 1.00 cop table:partsupp, index:PS_PARTKEY, PS_SUPPKEY, range: decided by [tpch.part.p_partkey], keep order:false + │ └─TableScan_57 1.00 cop table:partsupp, keep order:false + └─TableReader_80 44189356.65 root data:Selection_79 + └─Selection_79 44189356.65 cop ge(tpch.lineitem.l_shipdate, 1993-01-01 00:00:00.000000), lt(tpch.lineitem.l_shipdate, 1994-01-01) + └─TableScan_78 300005811.00 cop table:lineitem, range:[-inf,+inf], keep order:false /* Q21 Suppliers Who Kept Orders Waiting Query This query identifies certain suppliers who were not able to ship required parts in a timely manner. @@ -1213,29 +1211,28 @@ numwait desc, s_name limit 100; id count task operator info -Projection_25 100.00 root tpch.supplier.s_name, 17_col_0 -└─TopN_28 100.00 root 17_col_0:desc, tpch.supplier.s_name:asc, offset:0, count:100 - └─HashAgg_31 320000.00 root group by:tpch.supplier.s_name, funcs:count(1), firstrow(tpch.supplier.s_name) - └─IndexJoin_37 3786715.90 root anti semi join, inner:IndexLookUp_36, outer key:l1.l_orderkey, inner key:l3.l_orderkey, other cond:ne(l3.l_suppkey, l1.l_suppkey), ne(l3.l_suppkey, tpch.supplier.s_suppkey) - ├─IndexJoin_81 4733394.87 root semi join, inner:IndexLookUp_80, outer key:l1.l_orderkey, inner key:l2.l_orderkey, other cond:ne(l2.l_suppkey, l1.l_suppkey), ne(l2.l_suppkey, tpch.supplier.s_suppkey) - │ ├─HashLeftJoin_87 5916743.59 root inner join, inner:TableReader_116, equal:[eq(tpch.supplier.s_nationkey, tpch.nation.n_nationkey)] - │ │ ├─HashLeftJoin_92 147918589.81 root inner join, inner:TableReader_113, equal:[eq(l1.l_suppkey, tpch.supplier.s_suppkey)] - │ │ │ ├─IndexJoin_99 147918589.81 root inner join, inner:IndexLookUp_98, outer key:tpch.orders.o_orderkey, inner key:l1.l_orderkey - │ │ │ │ ├─TableReader_108 36517371.00 root data:Selection_107 - │ │ │ │ │ └─Selection_107 36517371.00 cop eq(tpch.orders.o_orderstatus, "F") - │ │ │ │ │ └─TableScan_106 75000000.00 cop table:orders, range:[-inf,+inf], keep order:false - │ │ │ │ └─IndexLookUp_98 240004648.80 root - │ │ │ │ ├─IndexScan_95 1.00 cop table:l1, index:L_ORDERKEY, L_LINENUMBER, range: decided by [tpch.orders.o_orderkey], keep order:false - │ │ │ │ └─Selection_97 240004648.80 cop gt(l1.l_receiptdate, l1.l_commitdate) - │ │ │ │ └─TableScan_96 1.00 cop table:lineitem, keep order:false - │ │ │ └─TableReader_113 500000.00 root data:TableScan_112 - │ │ │ └─TableScan_112 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false - │ │ └─TableReader_116 1.00 root data:Selection_115 - │ │ └─Selection_115 1.00 cop eq(tpch.nation.n_name, "EGYPT") - │ │ └─TableScan_114 25.00 cop table:nation, range:[-inf,+inf], keep order:false - │ └─IndexLookUp_80 1.00 root - │ ├─IndexScan_78 1.00 cop table:l2, index:L_ORDERKEY, L_LINENUMBER, range: decided by [l1.l_orderkey], keep order:false - │ └─TableScan_79 1.00 cop table:lineitem, keep order:false +Projection_25 1.00 root tpch.supplier.s_name, 17_col_0 +└─TopN_28 1.00 root 17_col_0:desc, tpch.supplier.s_name:asc, offset:0, count:100 + └─HashAgg_31 1.00 root group by:tpch.supplier.s_name, funcs:count(1), firstrow(tpch.supplier.s_name) + └─IndexJoin_37 7828961.66 root anti semi join, inner:IndexLookUp_36, outer key:l1.l_orderkey, inner key:l3.l_orderkey, other cond:ne(l3.l_suppkey, l1.l_suppkey), ne(l3.l_suppkey, tpch.supplier.s_suppkey) + ├─IndexJoin_53 9786202.08 root semi join, inner:IndexLookUp_52, outer key:l1.l_orderkey, inner key:l2.l_orderkey, other cond:ne(l2.l_suppkey, l1.l_suppkey), ne(l2.l_suppkey, tpch.supplier.s_suppkey) + │ ├─IndexJoin_59 12232752.60 root inner join, inner:TableReader_58, outer key:l1.l_orderkey, inner key:tpch.orders.o_orderkey + │ │ ├─HashRightJoin_63 12232752.60 root inner join, inner:HashRightJoin_69, equal:[eq(tpch.supplier.s_suppkey, l1.l_suppkey)] + │ │ │ ├─HashRightJoin_69 20000.00 root inner join, inner:TableReader_74, equal:[eq(tpch.nation.n_nationkey, tpch.supplier.s_nationkey)] + │ │ │ │ ├─TableReader_74 1.00 root data:Selection_73 + │ │ │ │ │ └─Selection_73 1.00 cop eq(tpch.nation.n_name, "EGYPT") + │ │ │ │ │ └─TableScan_72 25.00 cop table:nation, range:[-inf,+inf], keep order:false + │ │ │ │ └─TableReader_71 500000.00 root data:TableScan_70 + │ │ │ │ └─TableScan_70 500000.00 cop table:supplier, range:[-inf,+inf], keep order:false + │ │ │ └─TableReader_77 240004648.80 root data:Selection_76 + │ │ │ └─Selection_76 240004648.80 cop gt(l1.l_receiptdate, l1.l_commitdate) + │ │ │ └─TableScan_75 300005811.00 cop table:l1, range:[-inf,+inf], keep order:false + │ │ └─TableReader_58 36517371.00 root data:Selection_57 + │ │ └─Selection_57 36517371.00 cop eq(tpch.orders.o_orderstatus, "F") + │ │ └─TableScan_56 1.00 cop table:orders, range: decided by [l1.l_orderkey], keep order:false + │ └─IndexLookUp_52 1.00 root + │ ├─IndexScan_50 1.00 cop table:l2, index:L_ORDERKEY, L_LINENUMBER, range: decided by [l1.l_orderkey], keep order:false + │ └─TableScan_51 1.00 cop table:lineitem, keep order:false └─IndexLookUp_36 240004648.80 root ├─IndexScan_33 1.00 cop table:l3, index:L_ORDERKEY, L_LINENUMBER, range: decided by [l1.l_orderkey], keep order:false └─Selection_35 240004648.80 cop gt(l3.l_receiptdate, l3.l_commitdate) diff --git a/planner/core/cbo_test.go b/planner/core/cbo_test.go index 1b8f38645073d..9262984f72d78 100644 --- a/planner/core/cbo_test.go +++ b/planner/core/cbo_test.go @@ -386,7 +386,7 @@ func (s *testAnalyzeSuite) TestEmptyTable(c *C) { }, { sql: "select * from t where c1 in (select c1 from t1)", - best: "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t1)->HashAgg)->HashAgg}(test.t.c1,test.t1.c1)->Projection", + best: "RightHashJoin{TableReader(Table(t1)->HashAgg)->HashAgg->TableReader(Table(t))}(test.t1.c1,test.t.c1)->Projection", }, { sql: "select * from t, t1 where t.c1 = t1.c1", diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index dec7ba06af6cf..64dcf18ca5ac6 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -642,6 +642,7 @@ func (er *expressionRewriter) handleInSubquery(v *ast.PatternInExpr) (ast.Node, // We need to try to eliminate the agg and the projection produced by this operation. er.b.optFlag |= flagEliminateAgg er.b.optFlag |= flagEliminateProjection + er.b.optFlag |= flagJoinReOrderGreedy // Build distinct for the inner query. agg := er.b.buildDistinct(np, np.Schema().Len()) for _, col := range agg.schema.Columns { diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 8179ee33fbf87..b62ae1d734451 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -318,6 +318,7 @@ func (b *PlanBuilder) buildJoin(joinNode *ast.Join) (LogicalPlan, error) { joinPlan.JoinType = RightOuterJoin resetNotNullFlag(joinPlan.schema, 0, leftPlan.Schema().Len()) default: + b.optFlag = b.optFlag | flagJoinReOrderGreedy joinPlan.JoinType = InnerJoin } diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 10b5a25467798..486b1a93034c4 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -82,7 +82,7 @@ func (s *testPlanSuite) TestPredicatePushDown(c *C) { }, { sql: "select * from t t1, t t2 where t1.a = t2.b and t2.b > 0 and t1.a = t1.c and t1.d like 'abc' and t2.d = t1.d", - best: "Join{DataScan(t2)->Sel([like(cast(t2.d), abc, 92)])->DataScan(t1)->Sel([like(cast(t1.d), abc, 92)])}(t2.b,t1.a)(t2.d,t1.d)->Projection", + best: "Join{DataScan(t1)->Sel([like(cast(t1.d), abc, 92)])->DataScan(t2)->Sel([like(cast(t2.d), abc, 92)])}(t1.a,t2.b)(t1.d,t2.d)->Projection", }, { sql: "select * from t ta join t tb on ta.d = tb.d and ta.d > 1 where tb.a = 0", @@ -751,15 +751,15 @@ func (s *testPlanSuite) TestJoinReOrder(c *C) { }, { sql: "select * from t t1, t t2, t t3, t t4, t t5 where t1.a = t5.a and t5.a = t4.a and t4.a = t3.a and t3.a = t2.a and t2.a = t1.a and t1.a = t3.a and t2.a = t4.a and t3.b = 1 and t4.a = 1", - best: "Join{Join{Join{Join{DataScan(t3)->DataScan(t4)}->DataScan(t5)}->DataScan(t1)}->DataScan(t2)}->Projection", + best: "Join{Join{Join{DataScan(t3)->DataScan(t1)}->Join{DataScan(t2)->DataScan(t4)}}->DataScan(t5)}->Projection", }, { sql: "select * from t o where o.b in (select t3.c from t t1, t t2, t t3 where t1.a = t3.a and t2.a = t3.a and t2.a = o.a)", - best: "Apply{DataScan(o)->Join{Join{DataScan(t2)->DataScan(t3)}(t2.a,t3.a)->DataScan(t1)}(t3.a,t1.a)->Projection}->Projection", + best: "Apply{DataScan(o)->Join{Join{DataScan(t1)->DataScan(t3)}(t1.a,t3.a)->DataScan(t2)}(t3.a,t2.a)->Projection}->Projection", }, { sql: "select * from t o where o.b in (select t3.c from t t1, t t2, t t3 where t1.a = t3.a and t2.a = t3.a and t2.a = o.a and t1.a = 1)", - best: "Apply{DataScan(o)->Join{Join{DataScan(t1)->DataScan(t3)}->DataScan(t2)}->Projection}->Projection", + best: "Apply{DataScan(o)->Join{Join{DataScan(t3)->DataScan(t1)}->DataScan(t2)}->Projection}->Projection", }, } for _, tt := range tests { @@ -769,7 +769,7 @@ func (s *testPlanSuite) TestJoinReOrder(c *C) { p, err := BuildLogicalPlan(s.ctx, stmt, s.is) c.Assert(err, IsNil) - p, err = logicalOptimize(flagPredicatePushDown, p.(LogicalPlan)) + p, err = logicalOptimize(flagPredicatePushDown|flagJoinReOrderGreedy, p.(LogicalPlan)) c.Assert(err, IsNil) c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql)) } diff --git a/planner/core/optimizer.go b/planner/core/optimizer.go index 3065ebb1891d7..b7698ea3dd9dc 100644 --- a/planner/core/optimizer.go +++ b/planner/core/optimizer.go @@ -43,6 +43,7 @@ const ( flagPartitionProcessor flagPushDownAgg flagPushDownTopN + flagJoinReOrderGreedy ) var optRuleList = []logicalOptRule{ @@ -57,6 +58,7 @@ var optRuleList = []logicalOptRule{ &partitionProcessor{}, &aggregationPushDownSolver{}, &pushDownTopNOptimizer{}, + &joinReOrderGreedySolver{}, } // logicalOptRule means a logical optimizing rule, which contains decorrelate, ppd, column pruning, etc. diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index de02eef63fe03..bc65157a79ed7 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -281,7 +281,7 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) { }, { sql: "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a and t1.b = 1 and t3.c = 1", - best: "LeftHashJoin{IndexJoin{TableReader(Table(t)->Sel([eq(t1.b, 1)]))->TableReader(Table(t))}(t1.a,t2.a)->IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))}(t1.a,t3.a)", + best: "IndexJoin{IndexJoin{TableReader(Table(t)->Sel([eq(t1.b, 1)]))->IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))}(t3.a,t1.a)->TableReader(Table(t))}(t1.a,t2.a)->Projection", }, { sql: "select * from t where t.c in (select b from t s where s.a = t.a)", diff --git a/planner/core/rule_join_reorder.go b/planner/core/rule_join_reorder.go deleted file mode 100644 index 085ee11912007..0000000000000 --- a/planner/core/rule_join_reorder.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2016 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package core - -import ( - "sort" - - "github.com/pingcap/parser/ast" - "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/sessionctx" - log "github.com/sirupsen/logrus" -) - -// getCartesianJoinGroup collects all the inner join tables of a left deep join -// tree. The traversal of join tree is stopped and returns a nil group if: -// 1. reach a reordered join node, or: -// 2. reach a non-cartesian join node, or: -// 3. reach a join node which has a preferred join algorithm. -// 4. reach a straight join node. -// -// An example of left deep join tree is: -// -// "cartesian join 1" -// | \ -// | "right child 1" -// | -// "cartesian join 2" -// | \ -// | "right child 2" -// | -// "cartesian join ..." -// | \ -// | "right child ..." -// | -// "cartesian join n" -// | \ -// | "right child n" -// | -// "left deep child" -// -// The result of getCartesianJoinGroup is: -// {"left deep child", "right child n", ..., "right child 2", "right child 1"} -func getCartesianJoinGroup(p *LogicalJoin) []LogicalPlan { - if p.reordered || !p.cartesianJoin || p.preferJoinType > uint(0) || p.StraightJoin { - return nil - } - - lChild := p.children[0] - rChild := p.children[1] - - lhsJoinTree, ok := lChild.(*LogicalJoin) - if !ok { - return []LogicalPlan{lChild, rChild} - } - - lhsJoinGroup := getCartesianJoinGroup(lhsJoinTree) - if lhsJoinGroup == nil { - return nil - } - - return append(lhsJoinGroup, rChild) -} - -func findNodeIndexInGroup(groups []LogicalPlan, col *expression.Column) int { - for i, plan := range groups { - if plan.Schema().Contains(col) { - return i - } - } - log.Errorf("Unknown columns %s, position %d", col, col.UniqueID) - return -1 -} - -type joinReOrderSolver struct { - graph []edgeList - group []LogicalPlan - visited []bool - resultJoin LogicalPlan - groupRank []*rankInfo - ctx sessionctx.Context -} - -type edgeList []*rankInfo - -func (l edgeList) Len() int { - return len(l) -} - -func (l edgeList) Less(i, j int) bool { - return l[i].rate < l[j].rate -} - -func (l edgeList) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -type rankInfo struct { - nodeID int - rate float64 -} - -func (e *joinReOrderSolver) Less(i, j int) bool { - return e.groupRank[i].rate < e.groupRank[j].rate -} - -func (e *joinReOrderSolver) Swap(i, j int) { - e.groupRank[i], e.groupRank[j] = e.groupRank[j], e.groupRank[i] -} - -func (e *joinReOrderSolver) Len() int { - return len(e.groupRank) -} - -// reorderJoin implements a simple join reorder algorithm. It will extract all the equal conditions and compose them to a graph. -// Then walk through the graph and pick the nodes connected by some edges to compose a join tree. -// We will pick the node with least result set as early as possible. -func (e *joinReOrderSolver) reorderJoin(group []LogicalPlan, conds []expression.Expression) { - e.graph = make([]edgeList, len(group)) - e.group = group - e.visited = make([]bool, len(group)) - e.resultJoin = nil - e.groupRank = make([]*rankInfo, len(group)) - for i := 0; i < len(e.groupRank); i++ { - e.groupRank[i] = &rankInfo{ - nodeID: i, - rate: 1.0, - } - } - for _, cond := range conds { - if f, ok := cond.(*expression.ScalarFunction); ok { - if f.FuncName.L == ast.EQ { - lCol, lok := f.GetArgs()[0].(*expression.Column) - rCol, rok := f.GetArgs()[1].(*expression.Column) - if lok && rok { - lID := findNodeIndexInGroup(group, lCol) - rID := findNodeIndexInGroup(group, rCol) - if lID != rID { - e.graph[lID] = append(e.graph[lID], &rankInfo{nodeID: rID}) - e.graph[rID] = append(e.graph[rID], &rankInfo{nodeID: lID}) - continue - } - } - } - id := -1 - rate := 1.0 - cols := expression.ExtractColumns(f) - for _, col := range cols { - idx := findNodeIndexInGroup(group, col) - if id == -1 { - switch f.FuncName.L { - case ast.EQ: - rate *= 0.1 - case ast.LT, ast.LE, ast.GE, ast.GT: - rate *= 0.3 - // TODO: Estimate it more precisely in future. - default: - rate *= 0.9 - } - id = idx - } else { - id = -1 - break - } - } - if id != -1 { - e.groupRank[id].rate *= rate - } - } - } - for _, node := range e.graph { - for _, edge := range node { - edge.rate = e.groupRank[edge.nodeID].rate - } - } - sort.Sort(e) - for _, edge := range e.graph { - sort.Sort(edge) - } - var cartesianJoinGroup []LogicalPlan - for j := 0; j < len(e.groupRank); j++ { - i := e.groupRank[j].nodeID - if !e.visited[i] { - e.resultJoin = e.group[i] - e.walkGraphAndComposeJoin(i) - cartesianJoinGroup = append(cartesianJoinGroup, e.resultJoin) - } - } - e.makeBushyJoin(cartesianJoinGroup) -} - -// Make cartesian join as bushy tree. -func (e *joinReOrderSolver) makeBushyJoin(cartesianJoinGroup []LogicalPlan) { - for len(cartesianJoinGroup) > 1 { - resultJoinGroup := make([]LogicalPlan, 0, len(cartesianJoinGroup)) - for i := 0; i < len(cartesianJoinGroup); i += 2 { - if i+1 == len(cartesianJoinGroup) { - resultJoinGroup = append(resultJoinGroup, cartesianJoinGroup[i]) - break - } - resultJoinGroup = append(resultJoinGroup, e.newJoin(cartesianJoinGroup[i], cartesianJoinGroup[i+1])) - } - cartesianJoinGroup = resultJoinGroup - } - e.resultJoin = cartesianJoinGroup[0] -} - -func (e *joinReOrderSolver) newJoin(lChild, rChild LogicalPlan) *LogicalJoin { - join := LogicalJoin{ - JoinType: InnerJoin, - reordered: true, - }.Init(e.ctx) - join.SetSchema(expression.MergeSchema(lChild.Schema(), rChild.Schema())) - join.SetChildren(lChild, rChild) - return join -} - -// walkGraph implements a dfs algorithm. Each time it picks a edge with lowest rate, which has been sorted before. -func (e *joinReOrderSolver) walkGraphAndComposeJoin(u int) { - e.visited[u] = true - for _, edge := range e.graph[u] { - v := edge.nodeID - if !e.visited[v] { - e.resultJoin = e.newJoin(e.resultJoin, e.group[v]) - e.walkGraphAndComposeJoin(v) - } - } -} diff --git a/planner/core/rule_join_reorder_dp.go b/planner/core/rule_join_reorder_dp.go index 0864bf864e8c6..a7a70731bf4d1 100644 --- a/planner/core/rule_join_reorder_dp.go +++ b/planner/core/rule_join_reorder_dp.go @@ -47,8 +47,14 @@ func (s *joinReorderDPSolver) solve(joinGroup []LogicalPlan, conds []expression. sf := cond.(*expression.ScalarFunction) lCol := sf.GetArgs()[0].(*expression.Column) rCol := sf.GetArgs()[1].(*expression.Column) - lIdx := findNodeIndexInGroup(joinGroup, lCol) - rIdx := findNodeIndexInGroup(joinGroup, rCol) + lIdx, err := findNodeIndexInGroup(joinGroup, lCol) + if err != nil { + return nil, err + } + rIdx, err := findNodeIndexInGroup(joinGroup, rCol) + if err != nil { + return nil, err + } addEdge(lIdx, rIdx, sf) } visited := make([]bool, len(joinGroup)) @@ -179,3 +185,12 @@ func (s *joinReorderDPSolver) makeBushyJoin(cartesianJoinGroup []LogicalPlan) Lo } return cartesianJoinGroup[0] } + +func findNodeIndexInGroup(group []LogicalPlan, col *expression.Column) (int, error) { + for i, plan := range group { + if plan.Schema().Contains(col) { + return i, nil + } + } + return -1, ErrUnknownColumn.GenWithStackByArgs(col, "JOIN REORDER RULE") +} diff --git a/planner/core/rule_join_reorder_greedy.go b/planner/core/rule_join_reorder_greedy.go new file mode 100644 index 0000000000000..dcfa9d763acea --- /dev/null +++ b/planner/core/rule_join_reorder_greedy.go @@ -0,0 +1,228 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "math" + "sort" + + "github.com/pingcap/parser/ast" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/sessionctx" +) + +// extractJoinGroup extracts all the join nodes connected with continuous +// InnerJoins to construct a join group. This join group is further used to +// construct a new join order based on a greedy algorithm. +// +// For example: "InnerJoin(InnerJoin(a, b), LeftJoin(c, d))" +// results in a join group {a, b, LeftJoin(c, d)}. +func extractJoinGroup(p LogicalPlan) (group []LogicalPlan, eqEdges []*expression.ScalarFunction, otherConds []expression.Expression) { + join, isJoin := p.(*LogicalJoin) + if !isJoin || join.preferJoinType > uint(0) || join.JoinType != InnerJoin || join.StraightJoin { + return []LogicalPlan{p}, nil, nil + } + + lhsGroup, lhsEqualConds, lhsOtherConds := extractJoinGroup(join.children[0]) + rhsGroup, rhsEqualConds, rhsOtherConds := extractJoinGroup(join.children[1]) + + group = append(group, lhsGroup...) + group = append(group, rhsGroup...) + eqEdges = append(eqEdges, join.EqualConditions...) + eqEdges = append(eqEdges, lhsEqualConds...) + eqEdges = append(eqEdges, rhsEqualConds...) + otherConds = append(otherConds, join.OtherConditions...) + otherConds = append(otherConds, lhsOtherConds...) + otherConds = append(otherConds, rhsOtherConds...) + return group, eqEdges, otherConds +} + +type joinReOrderGreedySolver struct { + ctx sessionctx.Context + curJoinGroup []LogicalPlan + eqEdges []*expression.ScalarFunction + otherConds []expression.Expression +} + +// solve reorders the join nodes in the group based on a greedy algorithm. +// +// For each node having a join equal condition with the current join tree in +// the group, calculate the cumulative join cost of that node and the join +// tree, choose the node with the smallest cumulative cost to join with the +// current join tree. +// +// cumulative join cost = RowCount(lhs) + RowCount(rhs) + RowCount(join) +// TODO: this formula can be updated to fit more case. +// +// For the nodes and join trees which don't have a join equal condition to +// connect them, we make a bushy join tree to do the cartesian joins finally. +func (s *joinReOrderGreedySolver) solve() (LogicalPlan, error) { + for _, node := range s.curJoinGroup { + _, err := node.deriveStats() + if err != nil { + return nil, err + } + } + sort.Slice(s.curJoinGroup, func(i, j int) bool { + return s.curJoinGroup[i].statsInfo().RowCount < s.curJoinGroup[j].statsInfo().RowCount + }) + + var cartesianGroup []LogicalPlan + for len(s.curJoinGroup) > 0 { + newNode, err := s.constructConnectedJoinTree() + if err != nil { + return nil, err + } + cartesianGroup = append(cartesianGroup, newNode) + } + + return s.makeBushyJoin(cartesianGroup), nil +} + +func (s *joinReOrderGreedySolver) constructConnectedJoinTree() (LogicalPlan, error) { + curJoinTree := s.curJoinGroup[0] + s.curJoinGroup = s.curJoinGroup[1:] + for { + bestCost := math.MaxFloat64 + bestIdx := -1 + var finalRemainOthers []expression.Expression + var bestJoin LogicalPlan + for i, node := range s.curJoinGroup { + newJoin, remainOthers := s.checkConnectionAndMakeJoin(curJoinTree, node) + if newJoin == nil { + continue + } + _, err := newJoin.deriveStats() + if err != nil { + return nil, err + } + curCost := curJoinTree.statsInfo().RowCount + newJoin.statsInfo().RowCount + node.statsInfo().RowCount + if bestCost > curCost { + bestCost = curCost + bestJoin = newJoin + bestIdx = i + finalRemainOthers = remainOthers + } + } + // If we could find more join node, meaning that the sub connected graph have been totally explored. + if bestJoin == nil { + break + } + curJoinTree = bestJoin + s.curJoinGroup = append(s.curJoinGroup[:bestIdx], s.curJoinGroup[bestIdx+1:]...) + s.otherConds = finalRemainOthers + } + return curJoinTree, nil +} + +func (s *joinReOrderGreedySolver) checkConnectionAndMakeJoin(leftNode, rightNode LogicalPlan) (LogicalPlan, []expression.Expression) { + var usedEdges []*expression.ScalarFunction + remainOtherConds := make([]expression.Expression, len(s.otherConds)) + copy(remainOtherConds, s.otherConds) + for _, edge := range s.eqEdges { + lCol := edge.GetArgs()[0].(*expression.Column) + rCol := edge.GetArgs()[1].(*expression.Column) + if leftNode.Schema().Contains(lCol) && rightNode.Schema().Contains(rCol) { + usedEdges = append(usedEdges, edge) + } else if rightNode.Schema().Contains(lCol) && leftNode.Schema().Contains(rCol) { + newSf := expression.NewFunctionInternal(s.ctx, ast.EQ, edge.GetType(), rCol, lCol).(*expression.ScalarFunction) + usedEdges = append(usedEdges, newSf) + } + } + if len(usedEdges) == 0 { + return nil, nil + } + newJoin := s.newCartesianJoin(leftNode, rightNode) + newJoin.EqualConditions = usedEdges + for _, eqCond := range newJoin.EqualConditions { + newJoin.LeftJoinKeys = append(newJoin.LeftJoinKeys, eqCond.GetArgs()[0].(*expression.Column)) + newJoin.RightJoinKeys = append(newJoin.RightJoinKeys, eqCond.GetArgs()[1].(*expression.Column)) + } + for i := len(remainOtherConds) - 1; i >= 0; i-- { + cols := expression.ExtractColumns(remainOtherConds[i]) + if newJoin.schema.ColumnsIndices(cols) != nil { + newJoin.OtherConditions = append(newJoin.OtherConditions, remainOtherConds[i]) + remainOtherConds = append(remainOtherConds[:i], remainOtherConds[i+1:]...) + } + } + return newJoin, remainOtherConds +} + +func (s *joinReOrderGreedySolver) makeBushyJoin(cartesianJoinGroup []LogicalPlan) LogicalPlan { + resultJoinGroup := make([]LogicalPlan, 0, (len(cartesianJoinGroup)+1)/2) + for len(cartesianJoinGroup) > 1 { + resultJoinGroup = resultJoinGroup[:0] + for i := 0; i < len(cartesianJoinGroup); i += 2 { + if i+1 == len(cartesianJoinGroup) { + resultJoinGroup = append(resultJoinGroup, cartesianJoinGroup[i]) + break + } + newJoin := s.newCartesianJoin(cartesianJoinGroup[i], cartesianJoinGroup[i+1]) + for i := len(s.otherConds) - 1; i >= 0; i-- { + cols := expression.ExtractColumns(s.otherConds[i]) + if newJoin.schema.ColumnsIndices(cols) != nil { + newJoin.OtherConditions = append(newJoin.OtherConditions, s.otherConds[i]) + s.otherConds = append(s.otherConds[:i], s.otherConds[i+1:]...) + } + } + resultJoinGroup = append(resultJoinGroup, newJoin) + } + cartesianJoinGroup, resultJoinGroup = resultJoinGroup, cartesianJoinGroup + } + return cartesianJoinGroup[0] +} + +func (s *joinReOrderGreedySolver) newCartesianJoin(lChild, rChild LogicalPlan) *LogicalJoin { + join := LogicalJoin{ + JoinType: InnerJoin, + reordered: true, + }.Init(s.ctx) + join.SetSchema(expression.MergeSchema(lChild.Schema(), rChild.Schema())) + join.SetChildren(lChild, rChild) + return join +} + +func (s *joinReOrderGreedySolver) optimize(p LogicalPlan) (LogicalPlan, error) { + s.ctx = p.context() + return s.optimizeRecursive(p) +} + +func (s *joinReOrderGreedySolver) optimizeRecursive(p LogicalPlan) (LogicalPlan, error) { + var err error + curJoinGroup, eqEdges, otherConds := extractJoinGroup(p) + if len(curJoinGroup) > 1 { + for i := range curJoinGroup { + curJoinGroup[i], err = s.optimizeRecursive(curJoinGroup[i]) + if err != nil { + return nil, err + } + } + s.curJoinGroup, s.eqEdges, s.otherConds = curJoinGroup, eqEdges, otherConds + p, err = s.solve() + if err != nil { + return nil, err + } + return p, nil + } + newChildren := make([]LogicalPlan, 0, len(p.Children())) + for _, child := range p.Children() { + newChild, err := s.optimizeRecursive(child) + if err != nil { + return nil, err + } + newChildren = append(newChildren, newChild) + } + p.SetChildren(newChildren...) + return p, nil +} diff --git a/planner/core/rule_predicate_push_down.go b/planner/core/rule_predicate_push_down.go index 86a9e1f14f1f1..e82c367946bda 100644 --- a/planner/core/rule_predicate_push_down.go +++ b/planner/core/rule_predicate_push_down.go @@ -111,13 +111,6 @@ func (p *LogicalTableDual) PredicatePushDown(predicates []expression.Expression) // PredicatePushDown implements LogicalPlan PredicatePushDown interface. func (p *LogicalJoin) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan) { simplifyOuterJoin(p, predicates) - joinGroup := getCartesianJoinGroup(p) - if joinGroup != nil { - e := joinReOrderSolver{ctx: p.ctx} - e.reorderJoin(joinGroup, predicates) - newJoin := e.resultJoin - return newJoin.PredicatePushDown(predicates) - } leftPlan := p.children[0] rightPlan := p.children[1] var equalCond []*expression.ScalarFunction