Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
69d4559e
Commit
69d4559e
authored
Aug 16, 2009
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MWL#17: Table elimination
- Better comments - More OOM checks sql/sql_select.cc: - Remove garbage code
parent
e845f0f8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
24 deletions
+72
-24
sql/opt_table_elimination.cc
sql/opt_table_elimination.cc
+72
-10
sql/sql_select.cc
sql/sql_select.cc
+0
-14
No files found.
sql/opt_table_elimination.cc
View file @
69d4559e
...
@@ -19,6 +19,25 @@
...
@@ -19,6 +19,25 @@
/*
/*
OVERVIEW
OVERVIEW
This file contains table elimination module. The idea behind table
elimination is as follows: suppose we have a left join
SELECT * FROM t1 LEFT JOIN
(t2 JOIN t3) ON t3.primary_key=t1.col AND
t4.primary_key=t2.col
such that
* columns of the inner tables are not used anywhere ouside the outer join
(not in WHERE, not in GROUP/ORDER BY clause, not in select list etc etc),
* inner side of the outer join is guaranteed to produce at most one matching
record combination for each record combination of outer tables.
then the inner side of the outer join can be removed from the query, as it
will always produce only one record combination (either real or
null-complemented one) and we don't care about what that record combination
is.
MODULE INTERFACE
The module has one entry point - eliminate_tables() function, which one
The module has one entry point - eliminate_tables() function, which one
needs to call (once) at some point before the join optimization.
needs to call (once) at some point before the join optimization.
eliminate_tables() operates over the JOIN structures. Logically, it
eliminate_tables() operates over the JOIN structures. Logically, it
...
@@ -38,6 +57,50 @@
...
@@ -38,6 +57,50 @@
by EXPLAIN code to check if the subquery should be shown in EXPLAIN.
by EXPLAIN code to check if the subquery should be shown in EXPLAIN.
Table elimination is redone on every PS re-execution.
Table elimination is redone on every PS re-execution.
IMPLEMENTATION
As said above, we can remove inner side of an outer join if it is
1. not referred to from any other parts of the query
2. always produces one matching record combination.
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
potentially be eliminated.
#2 is checked using a concept of values and modules that indicate
dependencies between them.
We start with
of certain values that functional dependencies between
them. There are two kinds of values:
*/
/*
A value
functional dependencies between two kinds of entities:
*/
class
Value_dep
;
class
Field_value
;
class
Table_value
;
class
Module_dep
;
class
Equality_module
;
class
Outer_join_module
;
class
Key_module
;
class
Table_elimination
;
/*
A value.
*/
*/
class
Value_dep
:
public
Sql_alloc
class
Value_dep
:
public
Sql_alloc
...
@@ -55,13 +118,9 @@ public:
...
@@ -55,13 +118,9 @@ public:
Value_dep
*
next
;
Value_dep
*
next
;
};
};
class
Field_value
;
class
Table_value
;
class
Outer_join_module
;
class
Key_module
;
/*
/*
A table field
. There is
only one such object for any tblX.fieldY
A table field
value. There is exactly
only one such object for any tblX.fieldY
- the field epends on its table and equalities
- the field epends on its table and equalities
- expressions that use the field are its dependencies
- expressions that use the field are its dependencies
*/
*/
...
@@ -87,7 +146,8 @@ public:
...
@@ -87,7 +146,8 @@ public:
/*
/*
A table.
A table value. There is one Table_value object for every table that can
potentially be eliminated.
- table depends on any of its unique keys
- table depends on any of its unique keys
- has its fields and embedding outer join as dependency.
- has its fields and embedding outer join as dependency.
*/
*/
...
@@ -221,6 +281,7 @@ public:
...
@@ -221,6 +281,7 @@ public:
MY_BITMAP
expr_deps
;
MY_BITMAP
expr_deps
;
};
};
static
static
bool
build_eq_deps_for_cond
(
Table_elimination
*
te
,
Equality_module
**
fdeps
,
bool
build_eq_deps_for_cond
(
Table_elimination
*
te
,
Equality_module
**
fdeps
,
uint
*
and_level
,
Item
*
cond
,
uint
*
and_level
,
Item
*
cond
,
...
@@ -244,6 +305,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
...
@@ -244,6 +305,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
#ifndef DBUG_OFF
#ifndef DBUG_OFF
static
void
dbug_print_deps
(
Table_elimination
*
te
);
static
void
dbug_print_deps
(
Table_elimination
*
te
);
#endif
#endif
/*******************************************************************************************/
/*******************************************************************************************/
/*
/*
...
@@ -538,8 +600,8 @@ Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fi
...
@@ -538,8 +600,8 @@ Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fi
static
static
bool
add_eq_dep
(
Table_elimination
*
te
,
Equality_module
**
eq_dep
,
bool
add_eq_dep
(
Table_elimination
*
te
,
Equality_module
**
eq_dep
,
uint
and_level
,
Item_func
*
cond
,
uint
and_level
,
Item_func
*
cond
,
Item
*
left
,
Item
*
right
,
Item
*
left
,
Item
*
right
,
table_map
usable_tables
)
table_map
usable_tables
)
{
{
if
((
left
->
used_tables
()
&
usable_tables
)
&&
if
((
left
->
used_tables
()
&
usable_tables
)
&&
!
(
right
->
used_tables
()
&
RAND_TABLE_BIT
)
&&
!
(
right
->
used_tables
()
&
RAND_TABLE_BIT
)
&&
...
@@ -565,7 +627,6 @@ bool add_eq_dep(Table_elimination *te, Equality_module **eq_dep,
...
@@ -565,7 +627,6 @@ bool add_eq_dep(Table_elimination *te, Equality_module **eq_dep,
}
}
}
}
/* Store possible eq field */
(
*
eq_dep
)
->
type
=
Module_dep
::
MODULE_EXPRESSION
;
//psergey-todo;
(
*
eq_dep
)
->
type
=
Module_dep
::
MODULE_EXPRESSION
;
//psergey-todo;
if
(
!
((
*
eq_dep
)
->
field
=
get_field_value
(
te
,
field
)))
if
(
!
((
*
eq_dep
)
->
field
=
get_field_value
(
te
,
field
)))
return
TRUE
;
return
TRUE
;
...
@@ -651,7 +712,8 @@ Outer_join_module *get_outer_join_dep(Table_elimination *te,
...
@@ -651,7 +712,8 @@ Outer_join_module *get_outer_join_dep(Table_elimination *te,
table_map
deps_map
)
table_map
deps_map
)
{
{
Outer_join_module
*
oj_dep
;
Outer_join_module
*
oj_dep
;
oj_dep
=
new
Outer_join_module
(
outer_join
,
my_count_bits
(
deps_map
));
if
(
!
(
oj_dep
=
new
Outer_join_module
(
outer_join
,
my_count_bits
(
deps_map
))))
return
NULL
;
te
->
n_outer_joins
++
;
te
->
n_outer_joins
++
;
/*
/*
...
...
sql/sql_select.cc
View file @
69d4559e
...
@@ -8967,20 +8967,6 @@ static void restore_prev_nj_state(JOIN_TAB *last)
...
@@ -8967,20 +8967,6 @@ static void restore_prev_nj_state(JOIN_TAB *last)
JOIN
*
join
=
last
->
join
;
JOIN
*
join
=
last
->
join
;
while
(
last_emb
)
while
(
last_emb
)
{
{
/*
psergey-elim: (nevermind)
new_prefix= cur_prefix & ~last;
if (!(new_prefix & cur_table_map)) // removed last inner table
{
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
}
else (current)
{
// Won't hurt doing it all the time:
join->cur_embedding_map |= ...;
}
else
*/
if
(
!
(
--
last_emb
->
nested_join
->
counter
))
if
(
!
(
--
last_emb
->
nested_join
->
counter
))
join
->
cur_embedding_map
&=
~
last_emb
->
nested_join
->
nj_map
;
join
->
cur_embedding_map
&=
~
last_emb
->
nested_join
->
nj_map
;
else
if
(
last_emb
->
nested_join
->
n_tables
-
1
==
else
if
(
last_emb
->
nested_join
->
n_tables
-
1
==
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment