Skip to content

Commit 1771449

Browse files
author
Jonas Oreland
committed
ndb - merge 70-spj-scan-scan to 72
2 parents e9bf748 + 03dda74 commit 1771449

6 files changed

+129
-49
lines changed

mysql-test/suite/ndb/r/ndb_join_pushdown.result

+30-28
Original file line numberDiff line numberDiff line change
@@ -2060,33 +2060,33 @@ drop table tx;
20602060
alter table t1 partition by key(a);
20612061
explain select count(*) from t1
20622062
join t1 as t2 on t2.a = t1.c
2063-
join t1 as t3 on t3.a = t1.c;
2063+
join t1 as t3 on t3.a = t1.d;
20642064
id select_type table type possible_keys key key_len ref rows Extra
20652065
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 Parent of 3 pushed join@1
20662066
1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.c 1 Child of 't1' in pushed join@1
2067-
1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t1.c 1 Child of 't1' in pushed join@1
2067+
1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t1.d 1 Child of 't1' in pushed join@1
20682068
select count(*) from t1
20692069
join t1 as t2 on t2.a = t1.c
2070-
join t1 as t3 on t3.a = t1.c;
2070+
join t1 as t3 on t3.a = t1.d;
20712071
count(*)
2072-
208
2072+
176
20732073
CREATE TABLE tx (
20742074
a int NOT NULL,
20752075
PRIMARY KEY (`a`)
20762076
);
20772077
delete from t1;
20782078
insert into tx values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
2079-
insert into t1 select 1, x1.a * 10+x2.a, 1, 0 from tx as x1 cross join tx as x2;
2079+
insert into t1 select 1, x1.a * 10+x2.a, 1, 1 from tx as x1 cross join tx as x2;
20802080
explain select count(*) from t1 as x1
20812081
join t1 as x2 on x2.a = x1.c and x1.b < 2
2082-
join t1 as x3 on x3.a = x1.c;
2082+
join t1 as x3 on x3.a = x1.d;
20832083
id select_type table type possible_keys key key_len ref rows Extra
20842084
1 SIMPLE x1 ALL NULL NULL NULL NULL 100 Parent of 3 pushed join@1; Using where with pushed condition
20852085
1 SIMPLE x2 ref PRIMARY PRIMARY 4 test.x1.c 1 Child of 'x1' in pushed join@1
2086-
1 SIMPLE x3 ref PRIMARY PRIMARY 4 test.x1.c 1 Child of 'x1' in pushed join@1
2086+
1 SIMPLE x3 ref PRIMARY PRIMARY 4 test.x1.d 1 Child of 'x1' in pushed join@1
20872087
select count(*) from t1 as x1
20882088
join t1 as x2 on x2.a = x1.c and x1.b < 2
2089-
join t1 as x3 on x3.a = x1.c;
2089+
join t1 as x3 on x3.a = x1.d;
20902090
count(*)
20912091
20000
20922092
drop table t1;
@@ -2925,20 +2925,22 @@ a3 b3 c3 d3 a3 b3 c3 d3
29252925
explain extended
29262926
select straight_join * from
29272927
t3 as x1
2928-
join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3
2929-
join t3 as x2 on x2.b3 = y1.b3
2928+
join t3 as y1 on y1.b3 = x1.b3 and y1.d3 = x1.d3
2929+
join t3 as x2 on x2.b3 = y1.b3+0
29302930
join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3;
29312931
id select_type table type possible_keys key key_len ref rows filtered Extra
2932-
1 SIMPLE x1 ALL b3,c3,c3_2 NULL NULL NULL 7 100.00 Parent of 4 pushed join@1
2932+
1 SIMPLE x1 ALL b3,c3,c3_2 NULL NULL NULL 7 100.00 Parent of 2 pushed join@1
29332933
1 SIMPLE y1 ref b3 b3 9 test.x1.b3,test.x1.d3 1 100.00 Child of 'x1' in pushed join@1; Using where
2934-
1 SIMPLE x2 ref b3,c3,c3_2 b3 4 test.x1.b3 1 100.00 Child of 'x1' in pushed join@1
2935-
1 SIMPLE y2 ref b3 b3 9 test.x2.c3,test.x1.c3 1 100.00 Child of 'x2' in pushed join@1; Using where
2934+
1 SIMPLE x2 ref b3,c3,c3_2 b3 4 func 1 100.00 Parent of 2 pushed join@2; Using where
2935+
1 SIMPLE y2 ref b3 b3 9 test.x2.c3,test.x1.c3 1 100.00 Child of 'x2' in pushed join@2; Using where
29362936
Warnings:
2937-
Note 1003 select straight_join `test`.`x1`.`a3` AS `a3`,`test`.`x1`.`b3` AS `b3`,`test`.`x1`.`c3` AS `c3`,`test`.`x1`.`d3` AS `d3`,`test`.`y1`.`a3` AS `a3`,`test`.`y1`.`b3` AS `b3`,`test`.`y1`.`c3` AS `c3`,`test`.`y1`.`d3` AS `d3`,`test`.`x2`.`a3` AS `a3`,`test`.`x2`.`b3` AS `b3`,`test`.`x2`.`c3` AS `c3`,`test`.`x2`.`d3` AS `d3`,`test`.`y2`.`a3` AS `a3`,`test`.`y2`.`b3` AS `b3`,`test`.`y2`.`c3` AS `c3`,`test`.`y2`.`d3` AS `d3` from `test`.`t3` `x1` join `test`.`t3` `y1` join `test`.`t3` `x2` join `test`.`t3` `y2` where ((`test`.`y1`.`d3` = `test`.`x1`.`d3`) and (`test`.`y1`.`b3` = `test`.`x1`.`b3`) and (`test`.`x2`.`b3` = `test`.`x1`.`b3`) and (`test`.`y2`.`d3` = `test`.`x1`.`c3`) and (`test`.`y2`.`b3` = `test`.`x2`.`c3`))
2937+
Note 9999 Can't push table 'x2' as child, column 'b3' does neither 'ref' a column nor a constant
2938+
Note 9999 Can't push table 'y2' as child of 'x1', column 'x2.c3' is outside scope of pushable join
2939+
Note 1003 select straight_join `test`.`x1`.`a3` AS `a3`,`test`.`x1`.`b3` AS `b3`,`test`.`x1`.`c3` AS `c3`,`test`.`x1`.`d3` AS `d3`,`test`.`y1`.`a3` AS `a3`,`test`.`y1`.`b3` AS `b3`,`test`.`y1`.`c3` AS `c3`,`test`.`y1`.`d3` AS `d3`,`test`.`x2`.`a3` AS `a3`,`test`.`x2`.`b3` AS `b3`,`test`.`x2`.`c3` AS `c3`,`test`.`x2`.`d3` AS `d3`,`test`.`y2`.`a3` AS `a3`,`test`.`y2`.`b3` AS `b3`,`test`.`y2`.`c3` AS `c3`,`test`.`y2`.`d3` AS `d3` from `test`.`t3` `x1` join `test`.`t3` `y1` join `test`.`t3` `x2` join `test`.`t3` `y2` where ((`test`.`y1`.`d3` = `test`.`x1`.`d3`) and (`test`.`y1`.`b3` = `test`.`x1`.`b3`) and (`test`.`y2`.`d3` = `test`.`x1`.`c3`) and (`test`.`y2`.`b3` = `test`.`x2`.`c3`) and (`test`.`x2`.`b3` = (`test`.`x1`.`b3` + 0)))
29382940
select straight_join * from
29392941
t3 as x1
2940-
join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3
2941-
join t3 as x2 on x2.b3 = y1.b3
2942+
join t3 as y1 on y1.b3 = x1.b3 and y1.d3 = x1.d3
2943+
join t3 as x2 on x2.b3 = y1.b3+0
29422944
join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3;
29432945
a3 b3 c3 d3 a3 b3 c3 d3 a3 b3 c3 d3 a3 b3 c3 d3
29442946
prepare stmt1 from
@@ -4773,21 +4775,21 @@ PRIMARY KEY (`a`,`b`)
47734775
insert into t2 values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
47744776
insert into t3 select 1, x1.a * 10+x2.a from t2 as x1 cross join t2 as x2;
47754777
explain select straight_join count(*) from t1 as x0
4776-
join t3 as x1 on x0.c=x1.a
4777-
join t1 as x2 on x0.c=x2.a
4778-
join t3 as x3 on x2.c=x3.a
4779-
join t1 as x4 on x0.d=x4.a and x3.b=x4.b;
4778+
join t3 as x1 on x1.a=x0.c
4779+
join t1 as x2 on x2.a=x0.d
4780+
join t3 as x3 on x3.a=x2.c
4781+
join t1 as x4 on x4.a=x0.d and x4.b=x3.b;
47804782
id select_type table type possible_keys key key_len ref rows Extra
47814783
1 SIMPLE x0 ALL NULL NULL NULL NULL 4 Parent of 5 pushed join@1
47824784
1 SIMPLE x1 ref PRIMARY PRIMARY 4 test.x0.c 1 Child of 'x0' in pushed join@1
4783-
1 SIMPLE x2 ref PRIMARY PRIMARY 4 test.x0.c 1 Child of 'x0' in pushed join@1
4785+
1 SIMPLE x2 ref PRIMARY PRIMARY 4 test.x0.d 1 Child of 'x0' in pushed join@1
47844786
1 SIMPLE x3 ref PRIMARY PRIMARY 4 test.x2.c 1 Child of 'x2' in pushed join@1
47854787
1 SIMPLE x4 eq_ref PRIMARY PRIMARY 8 test.x0.d,test.x3.b 1 Child of 'x3' in pushed join@1
47864788
select straight_join count(*) from t1 as x0
4787-
join t3 as x1 on x0.c=x1.a
4788-
join t1 as x2 on x0.c=x2.a
4789-
join t3 as x3 on x2.c=x3.a
4790-
join t1 as x4 on x0.d=x4.a and x3.b=x4.b;
4789+
join t3 as x1 on x1.a=x0.c
4790+
join t1 as x2 on x2.a=x0.d
4791+
join t3 as x3 on x3.a=x2.c
4792+
join t1 as x4 on x4.a=x0.d and x4.b=x3.b;
47914793
count(*)
47924794
4800
47934795
drop table t1;
@@ -5471,7 +5473,7 @@ counter_name spj_counts_at_end.val - spj_counts_at_startup.val
54715473
CONST_PRUNED_RANGE_SCANS_RECEIVED 6
54725474
LOCAL_TABLE_SCANS_SENT 248
54735475
PRUNED_RANGE_SCANS_RECEIVED 25
5474-
RANGE_SCANS_RECEIVED 722
5476+
RANGE_SCANS_RECEIVED 728
54755477
READS_RECEIVED 58
54765478
TABLE_SCANS_RECEIVED 248
54775479
drop table spj_counts_at_startup;
@@ -5483,9 +5485,9 @@ pruned_scan_count
54835485
sorted_scan_count
54845486
10
54855487
pushed_queries_defined
5486-
397
5488+
399
54875489
pushed_queries_dropped
54885490
11
54895491
pushed_queries_executed
5490-
544
5492+
547
54915493
set ndb_join_pushdown = @save_ndb_join_pushdown;

mysql-test/suite/ndb/t/ndb_join_pushdown.test

+17-17
Original file line numberDiff line numberDiff line change
@@ -1025,10 +1025,10 @@ connection spj;
10251025

10261026
explain select count(*) from t1
10271027
join t1 as t2 on t2.a = t1.c
1028-
join t1 as t3 on t3.a = t1.c;
1028+
join t1 as t3 on t3.a = t1.d;
10291029
select count(*) from t1
10301030
join t1 as t2 on t2.a = t1.c
1031-
join t1 as t3 on t3.a = t1.c;
1031+
join t1 as t3 on t3.a = t1.d;
10321032

10331033
# Test bushy join with pruned scan and larger result set.
10341034

@@ -1043,14 +1043,14 @@ delete from t1;
10431043

10441044
insert into tx values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
10451045

1046-
insert into t1 select 1, x1.a * 10+x2.a, 1, 0 from tx as x1 cross join tx as x2;
1046+
insert into t1 select 1, x1.a * 10+x2.a, 1, 1 from tx as x1 cross join tx as x2;
10471047

10481048
explain select count(*) from t1 as x1
10491049
join t1 as x2 on x2.a = x1.c and x1.b < 2
1050-
join t1 as x3 on x3.a = x1.c;
1050+
join t1 as x3 on x3.a = x1.d;
10511051
select count(*) from t1 as x1
10521052
join t1 as x2 on x2.a = x1.c and x1.b < 2
1053-
join t1 as x3 on x3.a = x1.c;
1053+
join t1 as x3 on x3.a = x1.d;
10541054

10551055
connection ddl;
10561056
drop table t1;
@@ -1656,14 +1656,14 @@ select straight_join *
16561656
explain extended
16571657
select straight_join * from
16581658
t3 as x1
1659-
join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3
1660-
join t3 as x2 on x2.b3 = y1.b3
1659+
join t3 as y1 on y1.b3 = x1.b3 and y1.d3 = x1.d3
1660+
join t3 as x2 on x2.b3 = y1.b3+0
16611661
join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3;
16621662
--sorted_result
16631663
select straight_join * from
16641664
t3 as x1
1665-
join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3
1666-
join t3 as x2 on x2.b3 = y1.b3
1665+
join t3 as y1 on y1.b3 = x1.b3 and y1.d3 = x1.d3
1666+
join t3 as x2 on x2.b3 = y1.b3+0
16671667
join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3;
16681668

16691669

@@ -3312,16 +3312,16 @@ connection spj;
33123312
insert into t3 select 1, x1.a * 10+x2.a from t2 as x1 cross join t2 as x2;
33133313

33143314
explain select straight_join count(*) from t1 as x0
3315-
join t3 as x1 on x0.c=x1.a
3316-
join t1 as x2 on x0.c=x2.a
3317-
join t3 as x3 on x2.c=x3.a
3318-
join t1 as x4 on x0.d=x4.a and x3.b=x4.b;
3315+
join t3 as x1 on x1.a=x0.c
3316+
join t1 as x2 on x2.a=x0.d
3317+
join t3 as x3 on x3.a=x2.c
3318+
join t1 as x4 on x4.a=x0.d and x4.b=x3.b;
33193319

33203320
select straight_join count(*) from t1 as x0
3321-
join t3 as x1 on x0.c=x1.a
3322-
join t1 as x2 on x0.c=x2.a
3323-
join t3 as x3 on x2.c=x3.a
3324-
join t1 as x4 on x0.d=x4.a and x3.b=x4.b;
3321+
join t3 as x1 on x1.a=x0.c
3322+
join t1 as x2 on x2.a=x0.d
3323+
join t3 as x3 on x3.a=x2.c
3324+
join t1 as x4 on x4.a=x0.d and x4.b=x3.b;
33253325

33263326
connection ddl;
33273327
drop table t1;

sql/abstract_query_plan.cc

+27
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,33 @@ namespace AQP
261261
return get_join_tab()->table;
262262
}
263263

264+
double Table_access::get_fanout() const
265+
{
266+
switch (get_access_type())
267+
{
268+
case AT_PRIMARY_KEY:
269+
case AT_UNIQUE_KEY:
270+
return 1.0;
271+
272+
case AT_ORDERED_INDEX_SCAN:
273+
DBUG_ASSERT(get_join_tab()->join->best_positions[m_tab_no].records_read>0.0);
274+
return get_join_tab()->join->best_positions[m_tab_no].records_read;
275+
276+
case AT_MULTI_PRIMARY_KEY:
277+
case AT_MULTI_UNIQUE_KEY:
278+
case AT_MULTI_MIXED:
279+
DBUG_ASSERT(get_join_tab()->join->best_positions[m_tab_no].records_read>0.0);
280+
return get_join_tab()->join->best_positions[m_tab_no].records_read;
281+
282+
case AT_TABLE_SCAN:
283+
DBUG_ASSERT(get_join_tab()->table->file->stats.records>0.0);
284+
return static_cast<double>(get_join_tab()->table->file->stats.records);
285+
286+
default:
287+
return 99999999.0;
288+
}
289+
}
290+
264291
/** Get the JOIN_TAB object that corresponds to this operation.*/
265292
const JOIN_TAB* Table_access::get_join_tab() const
266293
{

sql/abstract_query_plan.h

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ namespace AQP
205205

206206
TABLE* get_table() const;
207207

208+
double get_fanout() const;
209+
208210
Item_equal* get_item_equal(const Item_field* field_item) const;
209211

210212
void dbug_print() const;

sql/ha_ndbcluster_push.cc

+41-4
Original file line numberDiff line numberDiff line change
@@ -1063,12 +1063,20 @@ ndb_pushed_builder_ctx::optimize_query_plan()
10631063
DBUG_ENTER("optimize_query_plan");
10641064
const uint root_no= m_join_root->get_access_no();
10651065

1066+
for (uint tab_no= root_no; tab_no<m_plan.get_access_count(); tab_no++)
1067+
{
1068+
if (m_join_scope.contain(tab_no))
1069+
{
1070+
m_tables[tab_no].m_fanout = m_plan.get_table_access(tab_no)->get_fanout();
1071+
m_tables[tab_no].m_child_fanout = 1.0;
1072+
}
1073+
}
1074+
10661075
// Find an optimal order for joining the tables
10671076
for (uint tab_no= m_plan.get_access_count()-1;
10681077
tab_no > root_no;
10691078
tab_no--)
10701079
{
1071-
struct pushed_tables &table= m_tables[tab_no];
10721080
if (!m_join_scope.contain(tab_no))
10731081
continue;
10741082

@@ -1078,6 +1086,7 @@ ndb_pushed_builder_ctx::optimize_query_plan()
10781086
* don't skip any dependent parents from our ancestors
10791087
* when selecting the actuall 'm_parent' to be used.
10801088
*/
1089+
pushed_tables &table= m_tables[tab_no];
10811090
if (!table.m_depend_parents.is_clear_all())
10821091
{
10831092
ndb_table_access_map const &dependency= table.m_depend_parents;
@@ -1115,12 +1124,40 @@ ndb_pushed_builder_ctx::optimize_query_plan()
11151124

11161125
/**
11171126
* In order to take advantage of the parallelism in the SPJ block;
1118-
* Choose the first possible parent candidate. Will result in the
1119-
* most 'bushy' query plan (aka: star-join)
1127+
* Initial parent candidate is the first possible among 'parents'.
1128+
* Will result in the most 'bushy' query plan (aka: star-join)
11201129
*/
11211130
parent_no= parents.first_table(root_no);
1131+
1132+
if (table.m_fanout*table.m_child_fanout > 1.0 ||
1133+
!ndbcluster_is_lookup_operation(m_plan.get_table_access(tab_no)->get_access_type()))
1134+
{
1135+
/**
1136+
* This is a index-scan or lookup with scan childs.
1137+
* Push optimization for index-scan execute:
1138+
*
1139+
* These are relative expensive operation which we try to avoid to
1140+
* execute whenever possible. By making them depending on parent
1141+
* operations with high selectivity, they will be eliminated when
1142+
* the parent returns no matching rows.
1143+
*
1144+
* -> Execute index-scan after any such parents
1145+
*/
1146+
for (uint candidate= parent_no+1; candidate<parents.length(); candidate++)
1147+
{
1148+
if (parents.contain(candidate))
1149+
{
1150+
if (m_tables[candidate].m_fanout > 1.0)
1151+
break;
1152+
1153+
parent_no= candidate; // Parent candidate is selective, eval after
1154+
}
1155+
}
1156+
}
1157+
11221158
DBUG_ASSERT(parent_no < tab_no);
11231159
table.m_parent= parent_no;
1160+
m_tables[parent_no].m_child_fanout*= table.m_fanout*table.m_child_fanout;
11241161

11251162
ndb_table_access_map dependency(table.m_depend_parents);
11261163
dependency.clear_bit(parent_no);
@@ -1134,7 +1171,7 @@ ndb_pushed_builder_ctx::optimize_query_plan()
11341171
{
11351172
if (m_join_scope.contain(tab_no))
11361173
{
1137-
struct pushed_tables &table= m_tables[tab_no];
1174+
pushed_tables &table= m_tables[tab_no];
11381175
const uint parent_no= table.m_parent;
11391176
table.m_ancestors= m_tables[parent_no].m_ancestors;
11401177
table.m_ancestors.add(parent_no);

sql/ha_ndbcluster_push.h

+12
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ class ndb_pushed_builder_ctx
283283
m_depend_parents(),
284284
m_parent(MAX_TABLES),
285285
m_ancestors(),
286+
m_fanout(1.0),
287+
m_child_fanout(1.0),
286288
m_op(NULL)
287289
{}
288290

@@ -317,6 +319,16 @@ class ndb_pushed_builder_ctx
317319
*/
318320
ndb_table_access_map m_ancestors;
319321

322+
/**
323+
* The fanout of this table.
324+
*/
325+
double m_fanout;
326+
327+
/**
328+
* The (cross) product of all child fanouts.
329+
*/
330+
double m_child_fanout;
331+
320332
const NdbQueryOperationDef* m_op;
321333
} m_tables[MAX_TABLES];
322334

0 commit comments

Comments
 (0)