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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
24c2fea6
Commit
24c2fea6
authored
Sep 02, 2009
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MWL#17: Table elimination
- Address review feedback R4: better comments, formatting
parent
d762bf21
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
32 deletions
+44
-32
sql-bench/test-table-elimination.sh
sql-bench/test-table-elimination.sh
+0
-4
sql/opt_table_elimination.cc
sql/opt_table_elimination.cc
+44
-28
No files found.
sql-bench/test-table-elimination.sh
View file @
24c2fea6
...
@@ -290,10 +290,6 @@ print "time for select_one_attribute ($count:$rows): " .
...
@@ -290,10 +290,6 @@ print "time for select_one_attribute ($count:$rows): " .
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n
"
;
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n
"
;
###
### TODO...
###
;
;
####
####
...
...
sql/opt_table_elimination.cc
View file @
24c2fea6
...
@@ -24,8 +24,10 @@
...
@@ -24,8 +24,10 @@
elimination is as follows: suppose we have a left join
elimination is as follows: suppose we have a left join
SELECT * FROM t1 LEFT JOIN
SELECT * FROM t1 LEFT JOIN
(t2 JOIN t3) ON t3.primary_key=t1.col AND
(t2 JOIN t3) ON t2.primary_key=t1.col AND
t4.primary_key=t2.col
t2.primary_key=t2.col
WHERE ...
such that
such that
* columns of the inner tables are not used anywhere ouside the outer join
* 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),
(not in WHERE, not in GROUP/ORDER BY clause, not in select list etc etc),
...
@@ -41,11 +43,11 @@
...
@@ -41,11 +43,11 @@
MODULE INTERFACE
MODULE INTERFACE
================
================
The module has one entry point -
eliminate_tables() function, which one
The module has one entry point -
the eliminate_tables() function, which one
needs to call (once) at some point before
the
join optimization.
needs to call (once) at some point before join optimization.
eliminate_tables() operates over the JOIN structures. Logically, it
eliminate_tables() operates over the JOIN structures. Logically, it
removes the
right sides of outer join nests. Physically, it changes
the
removes the
inner tables of an outer join operation together with
the
following members:
operation itself. Physically, it changes the
following members:
* Eliminated tables are marked as constant and moved to the front of the
* Eliminated tables are marked as constant and moved to the front of the
join order.
join order.
...
@@ -119,13 +121,14 @@
...
@@ -119,13 +121,14 @@
= No outgoing edges. Once we reach it, we know we can eliminate the
= No outgoing edges. Once we reach it, we know we can eliminate the
outer join.
outer join.
A module may depend on multiple values, and hence its primary attribute is
A module may depend on multiple values, and hence its primary attribute is
the number of its
depedencie
s that are not bound.
the number of its
argument
s that are not bound.
The algorithm starts with equality nodes that don't have any incoming edges
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
(their expressions are either constant or depend only on tables that are
outside of the outer join in question) and performns a breadth-first
outside of the outer join in question) and performns a breadth-first
traversal. If we reach the outer join nest node, it means outer join is
traversal. If we reach the outer join nest node, it means outer join is
functionally dependent and can be eliminated. Otherwise it cannot be.
functionally dependent and can be eliminated. Otherwise it cannot be
eliminated.
HANDLING MULTIPLE NESTED OUTER JOINS
HANDLING MULTIPLE NESTED OUTER JOINS
====================================
====================================
...
@@ -230,8 +233,9 @@ class Dep_value_field : public Dep_value
...
@@ -230,8 +233,9 @@ class Dep_value_field : public Dep_value
Field
*
field
;
/* Field this object is representing */
Field
*
field
;
/* Field this object is representing */
/* Iteration over unbound modules that are our dependencies */
/* Iteration over unbound modules that are our dependencies */
virtual
Iterator
init_unbound_modules_iter
(
char
*
buf
);
Iterator
init_unbound_modules_iter
(
char
*
buf
);
virtual
Dep_module
*
get_next_unbound_module
(
Dep_analysis_context
*
dac
,
Iterator
iter
);
Dep_module
*
get_next_unbound_module
(
Dep_analysis_context
*
dac
,
Iterator
iter
);
void
make_unbound_modules_iter_skip_keys
(
Iterator
iter
);
void
make_unbound_modules_iter_skip_keys
(
Iterator
iter
);
...
@@ -269,9 +273,11 @@ const size_t Dep_value_field::iterator_size=
...
@@ -269,9 +273,11 @@ const size_t Dep_value_field::iterator_size=
/*
/*
A table value. There is one Dep_value_table object for every table that can
A table value. There is one Dep_value_table object for every table that can
potentially be eliminated.
potentially be eliminated.
Dependencies:
- table depends on any of its unique keys
Table becomes bound as soon as some of its unique keys becomes bound
- has its fields and embedding outer join as dependency
Once the table is bound:
- all of its fields are bound
- its embedding outer join has one less unknown argument
*/
*/
class
Dep_value_table
:
public
Dep_value
class
Dep_value_table
:
public
Dep_value
...
@@ -280,14 +286,15 @@ class Dep_value_table : public Dep_value
...
@@ -280,14 +286,15 @@ class Dep_value_table : public Dep_value
Dep_value_table
(
TABLE
*
table_arg
)
:
Dep_value_table
(
TABLE
*
table_arg
)
:
table
(
table_arg
),
fields
(
NULL
),
keys
(
NULL
)
table
(
table_arg
),
fields
(
NULL
),
keys
(
NULL
)
{}
{}
TABLE
*
table
;
TABLE
*
table
;
/* Table this object is representing */
Dep_value_field
*
fields
;
/* Ordered list of fields that belong to this table */
/* Ordered list of fields that belong to this table */
Dep_value_field
*
fields
;
Dep_module_key
*
keys
;
/* Ordered list of Unique keys in this table */
Dep_module_key
*
keys
;
/* Ordered list of Unique keys in this table */
/* Iteration over unbound modules that are our dependencies */
/* Iteration over unbound modules that are our dependencies */
Iterator
init_unbound_modules_iter
(
char
*
buf
);
Iterator
init_unbound_modules_iter
(
char
*
buf
);
Dep_module
*
get_next_unbound_module
(
Dep_analysis_context
*
dac
,
Iterator
iter
);
Dep_module
*
get_next_unbound_module
(
Dep_analysis_context
*
dac
,
Iterator
iter
);
static
const
size_t
iterator_size
;
static
const
size_t
iterator_size
;
private:
private:
class
Module_iter
class
Module_iter
...
@@ -295,7 +302,7 @@ class Dep_value_table : public Dep_value
...
@@ -295,7 +302,7 @@ class Dep_value_table : public Dep_value
public:
public:
/* Space for field iterator */
/* Space for field iterator */
char
buf
[
Dep_value_field
::
iterator_size
];
char
buf
[
Dep_value_field
::
iterator_size
];
/* !NULL <=> iterating over dep
endena
nt modules of this field */
/* !NULL <=> iterating over dep
dene
nt modules of this field */
Dep_value_field
*
field_dep
;
Dep_value_field
*
field_dep
;
bool
returned_goal
;
bool
returned_goal
;
};
};
...
@@ -339,7 +346,8 @@ class Dep_module : public Sql_alloc
...
@@ -339,7 +346,8 @@ class Dep_module : public Sql_alloc
/* Iteration over values that */
/* Iteration over values that */
typedef
char
*
Iterator
;
typedef
char
*
Iterator
;
virtual
Iterator
init_unbound_values_iter
(
char
*
buf
)
=
0
;
virtual
Iterator
init_unbound_values_iter
(
char
*
buf
)
=
0
;
virtual
Dep_value
*
get_next_unbound_value
(
Dep_analysis_context
*
dac
,
Iterator
iter
)
=
0
;
virtual
Dep_value
*
get_next_unbound_value
(
Dep_analysis_context
*
dac
,
Iterator
iter
)
=
0
;
static
const
size_t
iterator_size
;
static
const
size_t
iterator_size
;
protected:
protected:
uint
unbound_args
;
uint
unbound_args
;
...
@@ -385,9 +393,9 @@ const size_t Dep_module_expr::iterator_size=
...
@@ -385,9 +393,9 @@ const size_t Dep_module_expr::iterator_size=
/*
/*
A Unique key
A Unique key
module
- Unique key
depends on all of its compon
ents
- Unique key
has all of its components as argum
ents
-
Key's table is its dependency
-
Once unique key is bound, its table value is known
*/
*/
class
Dep_module_key
:
public
Dep_module
class
Dep_module_key
:
public
Dep_module
...
@@ -539,8 +547,8 @@ void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
...
@@ -539,8 +547,8 @@ void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
The idea behind table elimination is that if we have an outer join:
The idea behind table elimination is that if we have an outer join:
SELECT * FROM t1 LEFT JOIN
SELECT * FROM t1 LEFT JOIN
(t2 JOIN t3) ON t
3
.primary_key=t1.col AND
(t2 JOIN t3) ON t
2
.primary_key=t1.col AND
t
4
.primary_key=t2.col
t
3
.primary_key=t2.col
such that
such that
1. columns of the inner tables are not used anywhere ouside the outer
1. columns of the inner tables are not used anywhere ouside the outer
...
@@ -559,8 +567,8 @@ void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
...
@@ -559,8 +567,8 @@ void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
tables that are not used in select list/GROUP BY/ORDER BY/HAVING/etc and
tables that are not used in select list/GROUP BY/ORDER BY/HAVING/etc and
thus can possibly be eliminated.
thus can possibly be eliminated.
After this, if #1 is met, the function calls eliminate_tables_for_list()
After this, if #1 is met, the function calls eliminate_tables_for_list()
that checks #2.
that checks #2.
SIDE EFFECTS
SIDE EFFECTS
See the OVERVIEW section at the top of this file.
See the OVERVIEW section at the top of this file.
...
@@ -656,7 +664,14 @@ void eliminate_tables(JOIN *join)
...
@@ -656,7 +664,14 @@ void eliminate_tables(JOIN *join)
select list, HAVING, other ON expressions, etc).
select list, HAVING, other ON expressions, etc).
DESCRIPTION
DESCRIPTION
Perform table elimination in a given join list.
Perform table elimination in a given join list:
- First, walk through join list members and try doing table elimination for
them.
- Then, if the join list itself is an inner side of outer join
(on_expr!=NULL), then try to eliminate the entire join list.
See "HANDLING MULTIPLE NESTED OUTER JOINS" section at the top of this file
for more detailed description and justification.
RETURN
RETURN
TRUE The entire join list eliminated
TRUE The entire join list eliminated
...
@@ -1677,7 +1692,8 @@ Dep_value::Iterator Dep_value_field::init_unbound_modules_iter(char *buf)
...
@@ -1677,7 +1692,8 @@ Dep_value::Iterator Dep_value_field::init_unbound_modules_iter(char *buf)
}
}
void
Dep_value_field
::
make_unbound_modules_iter_skip_keys
(
Dep_value
::
Iterator
iter
)
void
Dep_value_field
::
make_unbound_modules_iter_skip_keys
(
Dep_value
::
Iterator
iter
)
{
{
((
Module_iter
*
)
iter
)
->
key_dep
=
NULL
;
((
Module_iter
*
)
iter
)
->
key_dep
=
NULL
;
}
}
...
...
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