diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2009-08-16 21:01:59 +0300 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2009-08-16 21:01:59 +0300 |
commit | a14b5d2466915b3ef9aa4612cc74bdc8ab77f47c (patch) | |
tree | 94159970224ff7b4b3517b2ad2eeef43a67d1072 /sql/opt_table_elimination.cc | |
parent | 69d4559eed3dbe4273baf446b1ecd1df6111f341 (diff) | |
download | mariadb-git-a14b5d2466915b3ef9aa4612cc74bdc8ab77f47c.tar.gz |
MWL#17: Table elimination
- More comments
Diffstat (limited to 'sql/opt_table_elimination.cc')
-rw-r--r-- | sql/opt_table_elimination.cc | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 85d61fecd5d..a59151fc535 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -58,7 +58,7 @@ Table elimination is redone on every PS re-execution. - IMPLEMENTATION + TABLE ELIMINATION ALGORITHM As said above, we can remove inner side of an outer join if it is @@ -67,23 +67,59 @@ We check #1 by doing a recursive descent down the join->join_list while maintaining a union of used_tables() attribute of all expressions we've seen - "elsewhere". When we encounter an outer join, we check if the bitmap of - tables on its inner side has intersection with tables that are used - elsewhere. No intersection means that inner side of the outer join could + "elsewhere". When we encounter an outer join, we check if the bitmap of + tables on its inner side has an intersection with tables that are used + elsewhere. No intersection means that inner side of the outer join could potentially be eliminated. - #2 is checked using a concept of values and modules that indicate - dependencies between them. + In order to check #2, one needs to prove that inner side of an outer join + is functionally dependent on the outside. We prove dependency by proving + functional dependency of intermediate objects: - We start with - of certain values that functional dependencies between - them. There are two kinds of values: -*/ + - Inner side of outer join is functionally dependent when each of its tables + are functionally dependent. (We assume a table is functionally dependent + when its dependencies allow to uniquely identify one table record, or no + records). -/* - A value + - Table is functionally dependent when it has got a unique key whose columns + are functionally dependent. - functional dependencies between two kinds of entities: + - A column is functionally dependent when we could locate an AND-part of a + certain ON clause in form + + tblX.columnY= expr + + where expr is functionally-depdendent. + + Apparently the above rules can be applied recursively. Also, certain entities + depend on multiple other entities. We model this by a bipartite graph which + has two kinds of nodes: + + Value nodes: + - Table column values (each is a value of tblX.columnY) + - Table nodes (each node represents a table inside an eliminable join nest). + each value is either bound (i.e. functionally dependent) or not. + + Module nodes: + - Nodes representing tblX.colY=expr equalities. Equality node has + = incoming edges from columns used in expr + = outgoing edge to tblX.colY column. + - Nodes representing unique keys. Unique key has + = incoming edges from key component value nodes + = outgoing edge to key's table node + - Inner side of outer join node. Outer join node has + = incoming edges from table value nodes + = No outgoing edges. Once we reach it, we know we can eliminate the + outer join. + A module may depend on multiple values, and hence its primary attribute is + the number of its depedencies that are not bound. + + The algorithm starts with equality nodes that don't have any incoming edges + (their expressions are either constant or depend only on tables that are + outside of any outer joins) and proceeds to traverse dependency->dependant + edges until we've other traversed everything (TODO rephrase elaborate), or + we've reached the point where all outer join modules have zero unsatisfied + dependencies. */ class Value_dep; |