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
44570d2b
Commit
44570d2b
authored
Jun 21, 2011
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
MWL#89
Automerged with 5.3.
parents
4058115c
a02682ab
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1034 additions
and
4022 deletions
+1034
-4022
mysql-test/r/subselect_mat_cost.result
mysql-test/r/subselect_mat_cost.result
+559
-3769
mysql-test/t/disabled.def
mysql-test/t/disabled.def
+0
-1
mysql-test/t/subselect_mat_cost.test
mysql-test/t/subselect_mat_cost.test
+411
-198
sql/item_subselect.cc
sql/item_subselect.cc
+11
-2
sql/item_subselect.h
sql/item_subselect.h
+15
-10
sql/opt_subselect.cc
sql/opt_subselect.cc
+37
-41
sql/sql_select.cc
sql/sql_select.cc
+1
-1
No files found.
mysql-test/r/subselect_mat_cost.result
View file @
44570d2b
This source diff could not be displayed because it is too large. You can
view the blob
instead.
mysql-test/t/disabled.def
View file @
44570d2b
...
...
@@ -13,4 +13,3 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists
read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists
main.subselect_mat_cost : MWL#89 tests that must be adjusted to the cost model introduced after the code review
mysql-test/t/subselect_mat_cost.test
View file @
44570d2b
This diff is collapsed.
Click to expand it.
sql/item_subselect.cc
View file @
44570d2b
...
...
@@ -38,11 +38,14 @@ Item_subselect::Item_subselect():
Item_result_field
(),
value_assigned
(
0
),
own_engine
(
0
),
thd
(
0
),
old_engine
(
0
),
used_tables_cache
(
0
),
have_to_be_excluded
(
0
),
const_item_cache
(
1
),
inside_first_fix_fields
(
0
),
done_first_fix_fields
(
FALSE
),
substitution
(
0
),
expr_cache
(
0
),
engine
(
0
),
forced_const
(
FALSE
),
eliminated
(
FALSE
),
expr_cache
(
0
),
forced_const
(
FALSE
),
substitution
(
0
),
engine
(
0
),
eliminated
(
FALSE
),
engine_changed
(
0
),
changed
(
0
),
is_correlated
(
FALSE
)
{
DBUG_ENTER
(
"Item_subselect::Item_subselect"
);
DBUG_PRINT
(
"enter"
,
(
"this: 0x%lx"
,
(
ulong
)
this
));
#ifndef DBUG_OFF
exec_counter
=
0
;
#endif
with_subselect
=
1
;
reset
();
/*
...
...
@@ -130,6 +133,10 @@ void Item_subselect::cleanup()
value_assigned
=
0
;
expr_cache
=
0
;
forced_const
=
FALSE
;
DBUG_PRINT
(
"info"
,
(
"exec_counter: %d"
,
exec_counter
));
#ifndef DBUG_OFF
exec_counter
=
0
;
#endif
DBUG_VOID_RETURN
;
}
...
...
@@ -548,7 +555,9 @@ bool Item_subselect::exec()
DBUG_EXECUTE_IF
(
"subselect_exec_fail"
,
return
1
;);
res
=
engine
->
exec
();
#ifndef DBUG_OFF
++
exec_counter
;
#endif
if
(
engine_changed
)
{
engine_changed
=
0
;
...
...
sql/item_subselect.h
View file @
44570d2b
...
...
@@ -52,6 +52,17 @@ class Item_subselect :public Item_result_field
bool
inside_first_fix_fields
;
bool
done_first_fix_fields
;
Item
*
expr_cache
;
/*
Set to TRUE if at optimization or execution time we determine that this
item's value is a constant. We need this member because it is not possible
to substitute 'this' with a constant item.
*/
bool
forced_const
;
#ifndef DBUG_OFF
/* Count the number of times this subquery predicate has been executed. */
uint
exec_counter
;
#endif
public:
/*
Used inside Item_subselect::fix_fields() according to this scenario:
...
...
@@ -66,19 +77,13 @@ class Item_subselect :public Item_result_field
substitution= NULL;
< Item_subselect::fix_fields
*/
/* TODO make this protected member again. */
Item
*
substitution
;
/* unit of subquery */
st_select_lex_unit
*
unit
;
Item
*
expr_cache
;
/* engine that perform execution of subselect (single select or union) */
/* TODO make this protected member again. */
subselect_engine
*
engine
;
/*
Set to TRUE if at optimization or execution time we determine that this
item's value is a constant. We need this member because it is not possible
to substitute 'this' with a constant item.
*/
bool
forced_const
;
/* unit of subquery */
st_select_lex_unit
*
unit
;
/* A reference from inside subquery predicate to somewhere outside of it */
class
Ref_to_outside
:
public
Sql_alloc
{
...
...
sql/opt_subselect.cc
View file @
44570d2b
...
...
@@ -4341,8 +4341,6 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
{
JOIN
*
outer_join
;
JOIN
*
inner_join
=
this
;
/* Number of (partial) rows of the outer JOIN filtered by the IN predicate. */
double
outer_record_count
;
/* Number of unique value combinations filtered by the IN predicate. */
double
outer_lookup_keys
;
/* Cost and row count of the unmodified subquery. */
...
...
@@ -4362,38 +4360,37 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
outer_join
=
unit
->
outer_select
()
?
unit
->
outer_select
()
->
join
:
NULL
;
if
(
outer_join
)
{
uint
outer_partial_plan_len
;
/*
The index of the last JOIN_TAB in the outer JOIN where in_subs is
attached (pushed to).
*/
uint
max_outer_join_tab_idx
;
/*
Make_cond_for_table is called for predicates only in the WHERE/ON
clauses. In all other cases, predicates are not pushed to any
JOIN_TAB, and their joi_tab_idx remains MAX_TABLES. Such predicates
JOIN_TAB, and their joi
n
_tab_idx remains MAX_TABLES. Such predicates
are evaluated for each complete row of the outer join.
*/
outer_partial_plan_len
=
(
in_subs
->
get_join_tab_idx
()
==
MAX_TABLES
)
?
outer_join
->
table_count
:
in_subs
->
get_join_tab_idx
()
+
1
;
outer_join
->
get_partial_cost_and_fanout
(
outer_partial_plan_len
,
DBUG_ASSERT
(
outer_join
->
table_count
>
0
);
max_outer_join_tab_idx
=
(
in_subs
->
get_join_tab_idx
()
==
MAX_TABLES
)
?
outer_join
->
table_count
-
1
:
in_subs
->
get_join_tab_idx
();
/*
TODO:
Currently outer_lookup_keys is computed as the number of rows in
the partial join including the JOIN_TAB where the IN predicate is
pushed to. In the general case this is a gross overestimate because
due to caching we are interested only in the number of unique keys.
The search key may be formed by columns from much fewer than all
tables in the partial join. Example:
select * from t1, t2 where t1.c1 = t2.key AND t2.c2 IN (select ...);
If the join order: t1, t2, the number of unique lookup keys is ~ to
the number of unique values t2.c2 in the partial join t1 join t2.
*/
outer_join
->
get_partial_cost_and_fanout
(
max_outer_join_tab_idx
,
table_map
(
-
1
),
&
dummy
,
&
outer_record_count
);
if
(
outer_join
->
table_count
>
outer_join
->
const_tables
)
{
outer_join
->
get_partial_cost_and_fanout
(
outer_partial_plan_len
,
in_subs
->
used_tables
(),
&
dummy
,
&
outer_lookup_keys
);
/*
outer_lookup_keys= prev_record_reads(outer_join->best_positions,
outer_partial_plan_len,
in_subs->used_tables());
*/
}
else
{
/* If all tables are constant, positions is undefined. */
outer_lookup_keys
=
1
;
}
&
outer_lookup_keys
);
}
else
{
...
...
@@ -4401,17 +4398,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
TODO: outer_join can be NULL for DELETE statements.
How to compute its cost?
*/
outer_record_count
=
1
;
outer_lookup_keys
=
1
;
outer_lookup_keys
=
1
;
}
/*
There cannot be more lookup keys than the total number of records.
TODO: this a temporary solution until we find a better way to compute
get_partial_join_cost() and prev_record_reads() in a consitent manner,
where it is guaranteed that (outer_lookup_keys <= outer_record_count).
*/
if
(
outer_lookup_keys
>
outer_record_count
)
outer_lookup_keys
=
outer_record_count
;
/*
B. Estimate the cost and number of records of the subquery both
...
...
@@ -4459,7 +4447,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
write_cost
*
inner_record_count_1
;
materialize_strategy_cost
=
materialization_cost
+
outer_
record_count
*
lookup_cost
;
outer_
lookup_keys
*
lookup_cost
;
/* C.2 Compute the cost of the IN=>EXISTS strategy. */
in_exists_strategy_cost
=
outer_lookup_keys
*
inner_read_time_2
;
...
...
@@ -4469,6 +4457,14 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
in_subs
->
in_strategy
&=
~
SUBS_MATERIALIZATION
;
else
in_subs
->
in_strategy
&=
~
SUBS_IN_TO_EXISTS
;
DBUG_PRINT
(
"info"
,
(
"mat_strategy_cost: %.2f, mat_cost: %.2f, write_cost: %.2f, lookup_cost: %.2f"
,
materialize_strategy_cost
,
materialization_cost
,
write_cost
,
lookup_cost
));
DBUG_PRINT
(
"info"
,
(
"inx_strategy_cost: %.2f, inner_read_time_2: %.2f"
,
in_exists_strategy_cost
,
inner_read_time_2
));
DBUG_PRINT
(
"info"
,(
"outer_lookup_keys: %.2f"
,
outer_lookup_keys
));
}
/*
...
...
@@ -4524,9 +4520,9 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
const_tables
!=
table_count
)
{
/*
The subquery was not reoptimized either because the user allowed only
the
IN-EXISTS strategy, or because materialization was not possible based on
semantic analysis. Cle
nup the original plan and reoptimize.
The subquery was not reoptimized either because the user allowed only
the IN-EXISTS strategy, or because materialization was not possible
based on semantic analysis. Clea
nup the original plan and reoptimize.
*/
for
(
uint
i
=
0
;
i
<
table_count
;
i
++
)
{
...
...
sql/sql_select.cc
View file @
44570d2b
...
...
@@ -6045,7 +6045,7 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
}
for
(
tab
=
first_depth_first_tab
(
this
),
i
=
const_tables
;
tab
;
(
i
<=
end_tab_idx
&&
tab
)
;
tab
=
next_depth_first_tab
(
this
,
tab
),
i
++
)
{
/*
...
...
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