Skip to content

Commit ad154cc

Browse files
author
Ole John Aske
committed
SPJ: Mayor refactoring of ha_ndbcluster_push.cc and the logic which build
the pushed query (or: NdbQueryDef). Previously the NdbQueryDef was build incremenataly as we analyzed the query plan for pushable operations. This had the disadvantage that we could take descission about parent - child relations at this stage which later prevented other child candidates to be appended to the pushed query. This refactoring extends 'class ndb_pushed_builder_ctx' such that it collects intermediate information about pushable operation, and possible parent candidates for each child operation. Furthermore, it breaks the pushability logic into multiple passes: 1 ANALYZE: Analyze each child candidate and add it to 'ndb_pushed_builder_ctx::m_join_scope' as 'pushable' if it qualifies as such. In addition possible parent candidates, and required (forced) parent dependencies are collected for each table. All non pushable operations should be identified during this pass such that only known pushable operations remains. 2 OPTIMIZE: Determine the parent to be used among the set of possible parents. This is decided based on simple heuristic where the goal is to employ conditional filters as soon as possible, reduce the fanout of intermediate results, and utilize the parallelism of the SPJ block whenever considdered optimal. 3 BUILD: Build the NdbQueryDef. The primary goal of this refactoring has been to provide a better platform for later improving the efficiency of the pushed queries being produced. It has not been the goal of this refactoring to change the pushability of any query in the existing MTR testsuite. However a few queries has improved its pushability as the 'analyze' phase now are able to force an artificial sequential dependency between tables which enables more child operations to be appended to the pushed query.
1 parent 3e096f7 commit ad154cc

7 files changed

+1447
-1161
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,8 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
406406
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
407407
1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
408408
Warnings:
409-
Note 1644 Table 'g1' not pushable, select list can't contain BLOB columns
410-
Note 1644 Table 'g2' not pushable, select list can't contain BLOB columns
409+
Note 1644 Table 'g1' is not pushable: select list can't contain BLOB columns
410+
Note 1644 Table 'g2' is not pushable: select list can't contain BLOB columns
411411
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
412412
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
413413
CREATE TABLE t1 (
@@ -960,8 +960,8 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
960960
1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
961961
1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
962962
Warnings:
963-
Note 1644 Table 'g1' not pushable, select list can't contain BLOB columns
964-
Note 1644 Table 'g2' not pushable, select list can't contain BLOB columns
963+
Note 1644 Table 'g1' is not pushable: select list can't contain BLOB columns
964+
Note 1644 Table 'g2' is not pushable: select list can't contain BLOB columns
965965
Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid`
966966
DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
967967
CREATE TABLE t1 (

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

+117-24
Large diffs are not rendered by default.

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

+63-8
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,7 @@ from t1
477477
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
478478
join t1 as t3 on t3.a = t2.c and t3.b = t1.c;
479479

480-
# t4 is NOT pushable as t2 & t3 does not have
481-
# a parent / grandparent relationship
480+
# t4 is pushable iff we force an artificial parental dependency between t2 & t3.
482481
explain extended
483482
select straight_join *
484483
from t1
@@ -526,10 +525,10 @@ from t1
526525
# may be made pushable by equality set replacement.
527526
#
528527
# BEWARE: mysqld optimizer may do its own replacement
529-
# before ha_ndbcluster analyze the AQP. We therefore
528+
# before ha_ndbcluster_push analyze the AQP. We therefore
530529
# provide multiple similar testcases and hope that
531530
# some of them will trigger the replacement code in
532-
# ha_ndbcluster :-o
531+
# ha_ndbcluster_push :-o
533532
explain extended
534533
select straight_join *
535534
from t1
@@ -608,6 +607,58 @@ from t1
608607
join t1 as t3 on t3.a = t1.c and t3.b = t1.d
609608
join t1 as t4 on t4.a = t3.c and t4.b = t1.b;
610609

610+
# Added more multidependency tests;
611+
#
612+
613+
explain extended
614+
select straight_join *
615+
from t1
616+
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
617+
join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d
618+
join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d
619+
join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c;
620+
621+
explain extended
622+
select straight_join *
623+
from t1
624+
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
625+
join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d
626+
join t1 as t3 on t3.a = t1.c and t3.b = t1.d
627+
join t1 as t3x on t3x.a = t3.c and t3x.b = t3.d
628+
join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c;
629+
630+
explain extended
631+
select straight_join *
632+
from t1
633+
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
634+
join t1 as t3 on t3.a = t1.c and t3.b = t1.d
635+
join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d
636+
join t1 as t3x on t3x.a = t3.c and t3x.b = t3.d
637+
join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c;
638+
639+
# 't3' is not referred as ancestor and should not be
640+
# included in the forced dependencies
641+
# (Depends directly on 't1' and can be bushy wrt. to
642+
# the other tables)
643+
explain extended
644+
select straight_join *
645+
from t1
646+
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
647+
join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d
648+
join t1 as t3 on t3.a = t1.c and t3.b = t1.d
649+
join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d
650+
join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c;
651+
652+
# 't3' is still independent - see comment above.
653+
explain extended
654+
select straight_join *
655+
from t1
656+
join t1 as t2 on t2.a = t1.a and t2.b = t1.b
657+
join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d
658+
join t1 as t3 on t3.a = t1.c and t3.b = t1.b
659+
join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d
660+
join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c;
661+
611662

612663
# Test a combination of pushed table scan (x, y)
613664
# & pushed EQ-bound (indexScan) (z, t1)
@@ -1459,18 +1510,22 @@ select *
14591510
from t1
14601511
join t1 as t2 on (t2.b = t1.b or t2.b = t1.a)
14611512
join t1 as t3 on t3.a = t2.a
1462-
join t1 as t4 on t4.a = t3.b
1463-
;
1513+
join t1 as t4 on t4.a = t3.b;
14641514

14651515
set ndb_join_pushdown=true;
14661516

1517+
explain extended
1518+
select *
1519+
from t1
1520+
join t1 as t2 on (t2.b = t1.b or t2.b = t1.a)
1521+
join t1 as t3 on t3.a = t2.a
1522+
join t1 as t4 on t4.a = t3.b;
14671523
--sorted_result
14681524
select *
14691525
from t1
14701526
join t1 as t2 on (t2.b = t1.b or t2.b = t1.a)
14711527
join t1 as t3 on t3.a = t2.a
1472-
join t1 as t4 on t4.a = t3.b
1473-
;
1528+
join t1 as t4 on t4.a = t3.b;
14741529

14751530
## Test subquery execution where 'Full scan on null key' strategy requires
14761531
## table scan execution in addition to the key lookup which was prepared

0 commit comments

Comments
 (0)